Fork me on GitHub
#clojure
<
2015-07-14
>
canweriotnow05:07:18

Any Clojure shops in Reykjavik seeking U.S. resident aliens?

Pablo Fernandez06:07:53

I’m constructing a hashmap and I want to add :port port to it, but only if port is non-nil and not -1. What’s the most idiomatic way of doing that?

andrewmcveigh06:07:52

@pupeno: I guess you’d use merge: (merge {:new ‘hashmap} (when (and port (not= -1 port)) {:port port})

Pablo Fernandez06:07:06

Is there a builtin way in Clojure of writing this without calling getPort twice? (if (not= -1 (.getPort parsed-uri)) (.getPort parsed-uri))... something like (return-if #(not= -1 %) (.getPort parsed-uri)) which would be trivial to implement.

andrewmcveigh07:07:03

@pupeno: sounds like if-let should help

cfleming08:07:33

@pupeno: I use this:

(defmacro assoc-if
  ; Needs to be a macro so kvs is not evaluated if not required
  [map test & kvs]
  `(if ~test
     (assoc ~map ~@kvs)
     ~map))

Pablo Fernandez08:07:10

@cfleming: macros are beautiful. Unfortunately, I was trying to do a minimal patch for Korma and I wouldn’t lightly add macros to other people’s source code. I wish Clojure had assoc-if.

cfleming08:07:17

So you can say (assoc-if params (and port (pos? port)) :port port)

cfleming08:07:47

I mostly use it in threading forms though:

(-> params
    (assoc-if (and port (pos? port)) :port port))

cfleming08:07:09

That’s useful since I often have multiple things I want to add conditionally to the same map.

Pablo Fernandez08:07:00

That makes sense. I’m looking forward to the day threading comes natural to me.

cfleming08:07:32

Yeah, I use it all the time - I recommend practising with it.

andrewmcveigh08:07:41

@cfleming: that’s about the same as (cond-> params (and port (pos? port)) (assoc :port port))

andrewmcveigh08:07:01

which is more flexible

cfleming08:07:17

Doesn’t that return nil if the condition is false, rather than the original map?

andrewmcveigh08:07:35

no, it return the map

cfleming08:07:49

In that case, that gets my vote

cfleming08:07:52

And it’s in core.

cfleming08:07:33

TIL, cond-> is lovely.

pesterhazy08:07:55

I always forget about cond->

Pablo Fernandez08:07:36

There should a service that emails you one Clojure function a day with the documentation.

pesterhazy08:07:45

Clojure gazette is a bit like that

borkdude09:07:58

@pupeno: I had a Twitter account like that. https://twitter.com/learnclojure

borkdude09:07:29

at some point I couldn't maintain it anymore, because I was too busy becoming a teacher...

borkdude09:07:46

and then someone else took over, I believe it was @fogus ...

bostonaholic15:07:40

when I ran the Columbus Clojure User Group we had a "Function of the Month" where someone would pick a random clojure function and present to everyone

bostonaholic15:07:04

we stole that from the Columbus Ruby Brigade which did a "Method of the Month"

coyotespike17:07:56

I'm using @yogthos' clj-pdf library to build a form, using templates which are applied to maps of values. To get database values in there, I want all the var's holding those maps of values to be evaluated at runtime. Using reset! on an atom and then deref'ing it won't work, as the dereferenced value has already been evaluated. I just tried wrapping all the vars in delay, and then in my function calling (map force content-vector), which also didn't work. This all feels wrong, like I'm overlooking something obvious.

coyotespike17:07:25

Like, I could wrap the entire thing in a function...but that's not very aesthetically pleasing

andrea.crotti17:07:08

if I have a namespace

andrea.crotti17:07:22

how do I dynamically get one of the symbols defined in it/

andrea.crotti17:07:34

from a string I mean?

tcrayford17:07:42

andrea.crotti: a: don't do that most of the time. b: find-var takes a symbol (iirc), you can make a symbol from a string

gtrak17:07:10

which can resolve more than vars, i guess find-var is more specific to vars

arrdem17:07:44

yogthos: ping

arrdem17:07:14

so what's with the :buf key

arrdem17:07:22

it seems like it's an escape hatch for spanning lines

yogthos17:07:22

oh it's used for lists

arrdem17:07:28

okay so yeah

yogthos17:07:58

I aggregate the current level of li there and then pop them off

yogthos17:07:11

probably should be renamed more specifically simple_smile

arrdem17:07:37

basically what I'm thinking is that :code can be modified to use the :buf accumulator, and then at the close of a code block you run the :code-formatter or whatever that's the identity by default but which I can use as a hook into pygments or whatever.

arrdem17:07:49

once I chuck my changes for yours 😛

yogthos18:07:43

might want to introduce a separate one though, otherwise if you'll get funky behavior for stuff nested in lists simple_smile

yogthos18:07:20

probably would make sense to rename :buf to :li-buf and add a separate :buf maybe?

yogthos18:07:27

a bit ugly as well I know simple_smile

arrdem18:07:03

yeah but it kinda comes with the territory. I was looking at the markdown spec wondering if it would be nicer to just chuck your code and the answer is no 😛

yogthos18:07:10

but the general approach of leveraging the code block to do some post processing I like simple_smile

arrdem18:07:42

yeah. really what I want to do is be able to use GH style trippletick and lang name.

arrdem18:07:53

code's on my other computer or I'd just paste it.

yogthos18:07:55

it does that already simple_smile

arrdem18:07:10

well yes but there's no way to hook into that and run it through a static formatter

arrdem18:07:12

that I saw

yogthos18:07:23

oh yeah I see what you mean

yogthos18:07:04

I think it would be nice to split out a transformer that aggregates lines given the delimiter

yogthos18:07:20

and then it could be used internally by codeblock but also would allow custom transformers to hook into it

arrdem18:07:14

Effort to be CommonMark compatible would be nice at some point 😛

spiralganglion18:07:17

@bostonaholic: should have done "function of the fortnight" - 2 a month, alliteration bonus!

spiralganglion18:07:06

I'm all about those bonuses.

noisesmith20:07:59

any leads on a good intro level guide to using kafka from clojure? the clj-kafka readme is not working for me, I follow the examples in my repl and get all sorts of errors

ghadi20:07:49

kafka is ... frustrating

ghadi20:07:52

operationally

ghadi20:07:35

noisesmith: post your stacktrace (to refheap maybe) and I'll try to give you some nuggets. We use Kafka at LivingSocial, but not through clj-kafka

noisesmith20:07:54

ghadi: cool, thanks

ragge20:07:05

@noisesmith: hey, what issues are you having with clj-kafka?

noisesmith20:07:54

@ragge: one message "WARN org.apache.zookeeper.ClientCnxn - Session 0x0 for server null, unexpected error, closing socket connection and attempting reconnect"

ragge20:07:20

@noisesmith: and what are you doing when you get that exception?

ragge20:07:26

@noisesmith: or warning rather

noisesmith20:07:36

@ragge: but I don't even know the difference between normal chatter and actual problems at this point

noisesmith20:07:45

trying to consume a message

ragge20:07:50

@noisesmith: haha, yeah, both zk and kafka are very chatty

ragge20:07:05

@noisesmith: have you specified a port in zookeeper.connect?

pleasetrythisathome20:07:34

hey is anyone here using circleci?

noisesmith20:07:38

yeah, and the walkthrough is such that I wasn't totally sure which port numbers to use literally, and which I had to adapt to my install, and where to find the numbers

noisesmith20:07:36

@ragge: I am starting to suspect I can't just start kafka and start interacting with it in the repl, and there is a big understanding of the architecture and API I need before I can start experimenting with it...

noisesmith20:07:15

hundreds of lines of info and warnings and I don't really know which parts I can ignore at this point

ragge20:07:24

@noisesmith: can you do stuff using kafka-console-consumer.sh and kafka-console-producer?

noisesmith20:07:39

haven't tried it yet, I'll check those out

ragge20:07:02

@noisesmith: yeah, might be worth making sure you can do something basic with those... publish in one shell, consume in another

ragge20:07:19

@noisesmith: like @ghadi said, operating kafka is...

ghadi20:07:47

it's generous with the inscrutable stacktraces.

ghadi20:07:18

If you're running kafka in dev mode, there are sometimes /tmp/zookeeper files that are ok to blow away

ragge20:07:47

and actually, given the error you're seeing, it might be worth starting with zookeeper, there's zkCli.sh for that

noisesmith20:07:56

ragge: interesting

ragge20:07:23

start it, and run connect 127.0.0.1:2181

noisesmith20:07:23

ragge: so establish that zookeeper is working on my machine as expected, from the shell, then establish that kafka works as expected from the shell, and finally kafka?

ragge20:07:29

or wherever your zk is

ghadi20:07:39

Reconnects are typical with ZK

ragge20:07:39

sounds like the right order

ragge20:07:32

yeah, I guess it depends on what your setup is... just local dev stuff or some more realistic setup

noisesmith20:07:41

local dev right now

noisesmith20:07:52

but I'll need to do a proper install eventually too

noisesmith20:07:14

I've been nominated to become "the kafka guy" for our product

noisesmith20:07:25

which as of yet has no usage of kafka simple_smile

ragge20:07:30

well, good luck, let me know if you have any issues with clj-kafka, I'm partially guilty for that library so I'd be happy to help

noisesmith20:07:38

cool, thanks a lot

noisesmith20:07:53

I'll likely come back with more specific questions

pleasetrythisathome20:07:24

having trouble getting dependencies to cache correctly

pleasetrythisathome20:07:06

I have ~/.m2/repository in the dependency cache part of circle.yml

pleasetrythisathome20:07:29

and when sshing into the machine pre build, everything is getting copied correctly

pleasetrythisathome20:07:34

which is strange...

voxdolo20:07:13

we're not using any dependency caching, so I can't help there 😕 FWIW, it works fine without it… sounds like you're probably doing more with it than we are though.

pleasetrythisathome20:07:24

yea it definitely works fine

pleasetrythisathome20:07:32

just takes about 20min to build

pleasetrythisathome20:07:53

which isn’t exactly ideal X_X

voxdolo20:07:58

oh, wow. we're at like 2:30-3min builds

pleasetrythisathome20:07:12

yea i have other projects like that. not exactly sure what deps take so long for this one, but there are a lot of them i guess

noisesmith20:07:26

what about using a caching repo that is closer to your network?

pleasetrythisathome20:07:52

what do you mean by caching repo?

noisesmith20:07:19

you can define a maven repo that grabs things from the upstream source and caches them / provides them

noisesmith20:07:51

but if you are using circleci's servers making one that is "close" may be easier said than done?

pleasetrythisathome20:07:01

yea that sounds great in principle

pleasetrythisathome20:07:08

but good point about “close"

noisesmith20:07:41

well, if eg. circleci is on aws, having a caching mvn repo on the same location would give you good throughput

pleasetrythisathome20:07:44

circleci is supposed to support caching, and it’s working in that the .m2 directory gets populated for new builds, but for some reason the builds don’t see it

noisesmith20:07:02

oh, circleci is supposed to support this already, I didn't realize

pleasetrythisathome20:07:34

is there something that maven does locally that determines whether deps are available locally or need to be fetched beyond just storing them in .m2?

pleasetrythisathome20:07:46

wondering if there’s some env var or something that’s missing

noisesmith20:07:52

deps are considered immutable unless SNAPSHOT

noisesmith20:07:23

and it should prefer the cache over fetching from remote, as long as this is all on the same machine and same user as before

pleasetrythisathome20:07:59

i think same user may be the problem. i believe the circle builds are all on different machines

noisesmith20:07:30

right, which is where having a maven repo "repeater" that is on the same local network (or shorter network distance) could make a difference

pleasetrythisathome20:07:35

and the cache is stored somewhere and then fetched by the new machine

pleasetrythisathome20:07:45

yea that’s interesting

noisesmith20:07:48

it isn't just pulled from the repo?

pleasetrythisathome20:07:04

not sure how they manage it. the project is pulled from a repo

pleasetrythisathome20:07:18

but the env caching is a different process

noisesmith20:07:22

here's the official maven docs on maintaining your own server that will mirror the official ones https://maven.apache.org/repository-management.html

noisesmith20:07:45

well, we are talking about two kinds of repo here - maven repo vs. git repo

pleasetrythisathome20:07:34

ah yea that’s confusing. but thanks i’ll look into the maven repo stuff

pleasetrythisathome20:07:08

originally coming to clojure without much java experience has left some knowledge gaps on some of the basic java management stuff

arohner21:07:05

@noisesmith: @pleasetrythisathome Circle caches your m2 repo between builds, and stores the cache in S3

arohner21:07:19

adding another cache shouldn’t help, unless something else is going wrong

arohner21:07:46

@pleasetrythisathome: is your Circle build getting to the test step, or is it exiting before then? i.e. do you see a “saving cache” step?

noisesmith21:07:10

arohner: thanks for the info

arohner21:07:11

also, are you doing anything special with your m2?

pleasetrythisathome21:07:28

@arohner: yea it’s getting to test

pleasetrythisathome21:07:06

i have cache_directories: - ~/.m2/repository

pleasetrythisathome21:07:20

sounds like that should be removed?

arohner21:07:31

@pleasetrythisathome: you probably shouldn’t need it, unless it’s failing to infer this is a Clojure project

arohner21:07:51

which is necessary when your project.clj can’t be read as EDN (there should be a warning on the page if so)

pleasetrythisathome21:07:38

i’m using boot, so there isn’t a project.clj

pleasetrythisathome21:07:43

which could be the entire problem

arohner21:07:19

does boot even put things in ~/.m2/?

pleasetrythisathome21:07:37

it definitely reads from there

martinklepsch21:07:57

Boot uses .m2 just like Leiningen

pleasetrythisathome21:07:33

martin any experience with circleci and boot?

martinklepsch21:07:28

I know a few people that run things with boot on CircleCI, don’t remember them having such issues

pleasetrythisathome21:07:56

caveat here, it works fine, deps just aren’t cached so the every dependency has to be downloaded for each build

arohner22:07:46

@pleasetrythisathome: AFAIK, Circle doesn’t have inference for boot, so you’ll have to manually setup caching

arohner22:07:00

on a lein project I have that can’t be inferred, I have:

arohner22:07:06

`dependencies: cache_directories: - "~/.m2/"`

arohner22:07:12

dependencies:
  cache_directories:
    - "~/.m2/“

martinklepsch22:07:54

I think when we set things up for CircleCI back then we had a Docker container as base that already had a populated ~/.m2

martinklepsch22:07:00

don’t exactly remember though

martinklepsch22:07:57

@arohner: does the dependency caching work by finding a file like project.clj and downloading listed dependencies?

arohner22:07:37

@martinklepsch: the caching process is agnostic. It adds directories to be cached based on files present in the source repo. The logic looks like “if there’s a project.clj, or pom.xml, add ~/.m2/ to the cache directories. If there’s a Gemfile, add whatever it is that ruby caches"

arohner22:07:44

and that cache process runs at the end of the dependencies step

martinklepsch22:07:13

that makes sense

martinklepsch22:07:35

You’d think one could write programs that can check which of those directories have been populated 🙈

arohner22:07:31

yeah, that’s a good idea

martinklepsch22:07:01

@arohner: you work at CircleCI, do you?

martinklepsch22:07:46

Remember, now. Stumbled upon your blog the other day for that CLJS module stuff simple_smile

pleasetrythisathome23:07:47

@arohner: thanks i’ll keep playing with it