Fork me on GitHub
#clojure
<
2018-02-26
>
seancorfield00:02:20

@noisesmith He meant let he told me later via DM.

sova-soars-the-sora05:02:32

Hello everyone. I'm interested in building some RPC based server/clients to work on a digital crypto asset.... i'm wondering how i could do this with clojure (instead of using gRPC with golang)

logistark12:02:14

Hi, is there any way to make an "api first" approach in Clojure? I am not finding any ring/compojure/compojure-api generator

curlyfry15:02:12

By "generator", do you mean for example a Leiningen template?

logistark17:02:21

No, i mean having a swagger api specification generate the compojure routing endpoints, and schema

qqq12:02:24

filter keeps all the elements that are true; is there a builtin that runs through the list, generates two lists, one of the true, one of the false ?

leonoel12:02:35

group-by ?

joaohgomes13:02:52

partition-by?

qqq13:02:33

group-by is the right solution; thanks @leonoel

mbjarland13:02:49

Assume I want to build a high-traffic clojure rest service router which is to be deployed in the cloud and dynamically scaled with new nodes etc, any opinions on what webserver to use in a critical production scenario like this? tomcat? aleph? jetty? undertow? I realize this is opinion based, but I also realize this is the kind of thing you only figure out once you go down the wrong path...I'd like to learn from wrong paths already taken if possible...

fmnoise14:02:46

I vote for aleph

mbjarland14:02:12

ok, was starting to think I had no takers : ) Why aleph and I assume running with aleph would mean not running in say jetty/tomcat etc? (I'm new to web apps with clojure)

fmnoise14:02:45

that's my preference because: - aleph is built on netty which is cool and fast async server - my boss has a lot of commits in it so I can get some knowledge from him without googling 😄 and yes, you don't need jetty/undertow

fmnoise14:02:01

and there's awesome manifold library https://github.com/ztellman/manifold which aleph also uses

fmnoise14:02:29

very minor indeed

noisesmith16:02:47

tomcat isn't your choice for light weight btw - it's nice if you want multiple jvm processes in one vm though

mbjarland10:02:44

@U4BEW7F61, @U5YTV5W2F, @noisesmith thanks all. We will throw some hours at a poc with aleph and see what we find. @noisesmithyeah, I would tend to agree, but lightweight is not necessarily the top priority here. I was looking more for existing high traffic deployments, ease of deployment, ease of ops, large/active community for solving production issues etc...i.e. pointy haired business drivers for a high-dollar production site rather than development ones.

noisesmith17:02:10

for ease, tomcat/beanstalk on aws is pretty solid and it has a push button GUI, for handling traffic aleph is going to beat out the rest

mbjarland19:02:50

@noisesmith Ok, that is very useful to know, after working with aws for many years and now having some exposure to gcloud, I would have to say that I would pick gcloud any day of the week...assuming you don't need datomic cloud or one of the oodles of services aws has piled on...and we don't. So gcloud and aleph seems like a good place to start. Thanks again!

fmnoise11:02:09

@U4VDXB2TU I use aleph with gcloud and it works just fine, pm me if you'll need some help with deployment

mbjarland12:02:44

@U4BEW7F61 I'm a few days out from actually considering the deployment pieces...I just might ping you once I get there and get lost in the un- mapped/documented terrain

mbjarland13:02:57

I have used various servers in past lives for java based apps, but I figured there are special considerations (production repl? upsides with executable jar instead of servlet container etc) when deploying with clojure

noisesmith16:02:34

you can get a repl in production regardless of container by using the socket repl startup arg or using the nrepl library and starting an nrepl server in your -main

noisesmith16:02:56

of course you shouldn't listen to any non local connections from that repl... - not secure at all

Jim Rootham22:02:10

I have noticed that lein new does not play well with cloning a github repository. I did not see any issues about this on the leinengen github repo. Has there been any discussion about fixing this?

pesterhazy23:02:46

When using clojure.walk/postwalk, is there a way to distinguish map k/v pairs (which are given as 2-element PersistentVectors) and regular 2-element vectors?

hiredman23:02:17

@jrootham how do the two have anything to do with each other at all?

hiredman23:02:34

lein new creates a new project, a cloned repo isn't a new project

pesterhazy23:02:03

For context, I'm walking {:a 1 :b [:c :2]}

carocad15:03:58

key-vals in clojure are actually Java Map.Entry implementations that are displayed as vectors in the repl since they also behave as vector. You could just check if the “vector” implements Map.Entry -> key-val, otherwise -> normal vector

pesterhazy15:03:53

that's the thing, postwalk doesn't preserve the type unfortunately: https://dev.clojure.org/jira/browse/CLJ-2031

pesterhazy15:03:11

the issue has 9 votes already

pesterhazy15:03:25

given the difficulty of figuring out JIRA's UI, that means that 9*x people have run into this issue, for a high number of x

carocad22:03:29

oh I was not aware of that gotcha. That is indeed annoying

pesterhazy23:02:21

and I only want to act on the k/v pair :a 1

Jim Rootham23:02:34

The easy way to create a new git project is to create it on github and clone it. That will create .gitignore, LICENSE, and README.md, if you run lein new on that those files get walked on.

hiredman23:02:24

yeah, I dunno, I've never seen it done it that order

Jim Rootham23:02:06

What's your workflow? If there is a trivial alternative I'm all ears.

hiredman23:02:07

I create a project locally, work on it for a while, later if I want to publish to github I create an empty repo there and push to it

hiredman23:02:36

it has never occurred to me to actually check the "Initialize this repository with a README" box when creating a repo on github

sundarj23:02:17

@jrootham could you not create your own lein template and do lein new mytemplate foo

greglook23:02:45

yeah, I usually lein new foo or copy the relevant bits from an existing project, then create an empty repo in github to push to

Jim Rootham23:02:04

Ah, hadn't considered that. Is there a public repository for templates? I am thinking someone might have already built this.

greglook23:02:32

$ lein new foo
$ cd foo
$ git init .
$ git remote add origin [email protected]:$USER/foo.git
$ git add .
$ git commit
$ git push -u origin master

Jim Rootham23:02:19

And then replace the LICENSE file with the github tool. Not too bad.

sundarj23:02:26

there is an 'app' template built into lein that includes a README, LICENSE, and gitignore, if you weren't aware: https://github.com/technomancy/leiningen/tree/master/resources/leiningen/new/app

Jim Rootham23:02:55

I am aware, those are the files I don't want from lein. Especially LICENSE

ProbablyJody23:02:46

Anyone have experience using data.finger-tree in production? It seems like the repo could use some love so I wasn’t entirely sure about it’s stability.

seancorfield23:02:23

@jody Many Clojure libraries are "complete" and/or "stable" so they often don't show much recent activity.

lwhorton23:02:35

hey guys I had a one-off question I’m hoping someone could help me with: what’s the idiomatic way to lazily read lines in a file for later processing? after some experimentation i came up with

(let [rdr (io/reader (io/resource path))]
    (letfn [(read-next []
              (lazy-seq
                (if-let [line (.readLine rdr)]
                  (cons line (read-next))
                  (do (.close rdr) nil))))]
      (read-next))))
I know that with-open exists to help close the resource, but it doesn’t work if you’re trying to return from a function some lazy sequence (i.e. you’re not doing all the processing in the body of the with-open). is there another way to handle this that I’m missing?

seancorfield23:02:09

Unlike other languages, Clojure tends to encourage very narrow-focused libraries so they do one thing and do it well.

ProbablyJody23:02:54

I figured as much. Thanks for the input!

seancorfield23:02:37

(that said, there certainly are abandoned libraries out there -- but even then, they tend to be fairly stable)

lwhorton23:02:48

^ @jody coming from the node/js/npm ecosystem it scared me too initially, that a lot of clojure libs are “stale”. I now take it as a good thing, not a bad, that I can use a 4 year old library written against some older version of clojure and everything still works. Welcome to the awesomeness of people who actually care about backwards compatibility.

ProbablyJody23:02:17

That is quite nice. lol

lwhorton23:02:05

in a lot of javascript ecosystems, if you arent just this side of the bleeding edge, nothing works. “ill just change this one package.json line” turns into days of reconciliation. nightmares persist.

yogidevbear23:02:12

Hi everyone. I'm really struggling with this one and I'm hoping someone can help me out. I've got a lot of the pieces in place, but it's my final recursive step that I'm having a mental block with. I have a 2 dimensional vector, e.g.:

[[0 0 2 0 0]
[0 2 2 0 0]
[0 0 0 2 0]
[2 0 2 0 0]]
I have a function that gets me the vertical / horizontal adjacent "cells" which I've named get-adjacent-points which accepts the X and Y points of the "cell" I'm navigating from. So if I specify get-adjacent-points [0 0]), I will get [[1 0][0 1] back. I've also got a function to check the value of a specific point which I've named get-point-value. Calling (get-point-value 0 0) will return 0, whereas calling (get-point-value 2 0) will return 2 (the third column value in the first row). I'm trying to figure out a way to combine these functions within another function (or more) where I can find all vertical/horizontal adjacent cells with the same value as my initial randomly selected cell and update those to a new value (in this example 1) and repeat the process finding related adjacent cells for those until I exhaust any adjacent cells with the same initial value. So using my initial 2D example above, if I started with [0 0], it would see the top left "cell" is a zero value, update it to be 1, find it's adjacent cells, and if any of those are zero, change them to 1, etc, ending up with a final value of:
[[1 1 2 0 0]
 [1 2 2 0 0]
 [1 1 1 2 0]
 [2 1 2 0 0]]
I've tried to be as descriptive as possible here. I hope the explanation makes sense. Thanks in advance for any help with this.

hiredman23:02:47

get-in and update-in

hiredman23:02:06

or switch to a map of {cord value} depending on what you are doing