Fork me on GitHub
#clojure
<
2017-05-29
>
souenzzo00:05:39

Is there any standard way operate with namespaced maps? My use case: I have a state and I use namespaces to keep (almost) all stuff on first level So I have, for example {:app/tab :page.foo.tab/first :app/page :page/foo :api/foo [:bar1 :bar2] :auth/token "123"} Sometimes, I want to dissoc all app atributes from this map. Today, I'm doing this (->> (keys state) (group-by namespace) :app (#(apply dissoc state %)))

nathanmarz01:05:02

@souenzzo with specter (setval [MAP-KEYS (selected? NAMESPACE #(= "app" %))] NONE data)

nathanmarz01:05:18

i'd guess at least 10x faster as well

danp04:05:29

Hi all, I've been trying to use a macro to wrap a Java builder, as explained in an SO post here: https://stackoverflow.com/questions/37503316/creating-a-clojure-macro-that-uses-a-string-to-call-a-java-function After reading it, it makes sense to just use interop as its expressive enough, but thought that it would be helpful to have the builder class itself wrapped in a function so a doc string could be associated with it for easy reference at the REPL. Is this a reasonable thing to do, or am I being unclojurey? 🙂

mdallastella07:05:53

'Morning. A quick question. We are developing a project which has 1 backend (ring and compojure-api) and 3 different interfaces (re-frame). Now we would like to split this huge project (and the git repositories) in 4 different subprojects. Any advice or thought about how we should proceed?

pesterhazy08:05:57

@mdallastella, my contrarian advice: keep everything in a single repository. Unless you're hitting git's limits (you shouldn't at this scale), splitting repos adds hardly any value and prevents useful hacks (like having a common library accessible from all subprojects, just by adding it to the source-paths)

pesterhazy08:05:17

Also in case of cross-cutting refactorings (e.g. renaming a keyword), you have the whole change in an atomic commit, not spread across multiple histories.

mdallastella08:05:43

@pesterhazy yeah, we cosidered to keep one projects and one of the pros were the common libraries

mdallastella08:05:22

I just have some doubts when we will deploy the entire project (and it's maintenance)... but we'll see

pesterhazy08:05:35

the alternative is to push individual libs to a private maven repository and use manual versioning to keep things up to date

yonatanel09:05:47

So, is there any activity or interest in clojure-on-go?

danielcompton10:05:14

@mdallastella as someone building a private Maven repo service, I have a slightly contrarian view to @pesterhazy 🙂, but I can't really disagree too much with him here. At Day8 we've considered a monorepo several times as we have a lot of shared library code between different projects, but it has worked better for us to split it out into separate projects. This is more a function of our org structure and release process though

danielcompton10:05:05

Question: Is there a way to force tools.namespace to always reload a namespace? I'm using hugsql, and I want to reload my hugsql definitions when the SQL file changes. I'm don't think I can do that with tools.namespace, so the next best thing is to always reload the namespace that defines the hugsql functions

andrea.crotti12:05:54

Is there a better way to rewrite this?

andrea.crotti12:05:57

(def directions
  {:north [dec identity]
   :east [identity inc]
   :south [inc identity]
   :west [identity dec]})

(defn move
  "Transform the coordinate to the given cardinal direction"
  [direction coord]
  (vec
   (let [funcs (direction directions)]
     (for [[f v] (zipmap funcs coord)]
       (f v)))))

tatut12:05:27

andrea.crotti:

(defn move [dir [y x]] (let [[y-f x-f] (directions dir)] [(y-f y) (x-f x)]))

tatut12:05:36

with proper indentation

andrea.crotti12:05:39

which is for example used as (move :north [0 0]) => [-1 0]

andrea.crotti12:05:12

I kind of think that for could be removed but not really sure how

jeff.terrell12:05:48

(defn move
  [direction [x y :as coord]]
  (let [[x-func y-func] (direction directions)]
    [(x-func x) (y-func y)]))

tatut12:05:06

almost exactly what I wrote

andrea.crotti12:05:56

mm nice, but it now depends on the fact that there are only 2 dimensions

andrea.crotti12:05:23

would it be possible to keep it more agnostic about the number of dimensions?

tatut12:05:35

so does your map of direction kw to vector of functions

tatut12:05:31

(mapv (fn [func coord] (func coord)) (directions :north) [0 0])

jeff.terrell12:05:08

@andrea.crotti - Not without a for or other loop. 😄

tatut12:05:53

I think mapv reads nicer than using vec, for and zipmap… but yes you need something like that

andrea.crotti12:05:39

changing it slightly from @tatut this works perfectly well

(def directions
  {:north [dec identity]
   :east [identity inc]
   :south [inc identity]
   :west [identity dec]})

(defn move
  "Transform the coordinate to the given cardinal direction"
  [direction coord]
  (mapv
   (fn [func c] (func c)) (direction directions) coord))

tatut12:05:29

or if we’re golfing, just (mapv #(%1 %2) (direction directions) coord)

andrea.crotti12:05:32

another thing I'm not too sure is using keywords as functions implicitly

andrea.crotti12:05:02

I mean maybe (get directions direction) is more explicit in this case?

andrea.crotti12:05:22

but probably it's fine, if it's common practice in Clojure anyway

tatut12:05:38

Or use the map as a function (directions direction), works either way

camdez13:05:47

Apologies if this comes up over and over, but the (supposedly required) name field on the Clojure contributor agreement is not a fillable field. Anyone else run into this?

rauh13:05:15

@camdez IIRC it'll be filled in when you click sign

camdez13:05:30

@rauh sigh You are correct. Highly non-obvious. Thanks!

daveliepmann13:05:55

That name field was an eyebrow-raising looks-like-a-bug for me, too.

qqq15:05:05

is there a way to get the size of a file without reading it ?

noisesmith15:05:50

+user=> (.length (java.io.File. "/home/justin/.profile"))
972

mpenet15:05:13

noisesmith: file.Files has a much faster method to do this. but you probably don't need to care

hswick15:05:09

@danp Wrapping the builder class in a function could be nice, but builders are often times specific. Writing a doc for it would be good for that use case, but not all. Sometimes the java interop is so easy that wrapping it doesnt give much of an advantage. Perhaps the thing you are using builder for should be documented.

qqq15:05:50

@noisesmith : a related questino: do I need to put that in an with-open ? when/when-not do file type resourceds need to be put in a with-open ?

noisesmith15:05:12

it doesn't open the file

noisesmith15:05:45

with-open is for InputStream, or other similar resources that have a .close method

qqq15:05:16

does antyghin in http://clojure.java.io/ need with-open ? or is it only when I do stuff like (java.io.ByteArrayOLutputStream. ...) ?

noisesmith15:05:29

it's for things that keep a socket or file descriptor and use it over multiple calls; since you have a limited set of descriptors you can use and it's a good idea to close them explicitly

qqq15:05:49

does the gc eventually call .close for me if I forget?

noisesmith15:05:55

but the main thing I'd check is if the object you created has a .close method - because with-open can't really help you if there's no .close

qqq15:05:59

or do I permenantely lose a descriptor if I forget to .close / with-open ?

noisesmith15:05:05

@qqq it might but I wouldn't count on it

noisesmith15:05:25

I guess we could make an experiment and find out

qqq15:05:44

this seems like one arena where C++ RAII beats out java gc

plexus16:05:14

I just noticed $project_dir/target/classes is by default on the classpath, at least when running with Leiningen... anyone know what's adding that?

plexus16:05:46

e.g. in a vanilla lein new empty-project ; lein repl ; (filter #(re-find #"target" %) (map str (.getURLs (java.lang.ClassLoader/getSystemClassLoader))))

plexus16:05:56

("file:/tmp/empty-project/target/classes/")

plexus16:05:53

I just spent at least an hour figuring out why tools.namespace was refusing to refresh without errors. Turned out it was getting messed up because of AOT compiled classes from a previous uberjar build

plexus16:05:19

I don't see a reason why target/classes should be on the class path when running a dev/repl environment, but maybe there's a reason?

qqq16:05:05

What is the difference between byte-array and java ByteBuffer ?

plexus16:05:42

@qqq ByteBuffer is a class, a byte-array returns a Java array of type byte[]

qqq16:05:43

Yes, but what are the benefits of each ?

plexus16:05:37

byte[] is really a low level data structure, I would probably only use it if either some library requires byte[] as input, or if I'm trying to write very specific optimized code

plexus16:05:44

I assume ByteBuffer really just wrapes a byte[] array, but it implements a bunch of higher level operations so you don't have to

danp16:05:29

@hswick cheers, the Java library is documented. I'll see how I go and if I'm constantly referring back to the javadoc, I'll write a function around the class and doc string it :)

plexus16:05:14

Bumping this just in case... I'm trying to figure out what is adding target/classes to the classpath... seems to be on there by default, not sure if it's Leiningen, Clojure or Java that's doing it

dpsutton16:05:50

@plexus is the issue also present in a boot project?

dpsutton16:05:01

i don't have boot on my work computer so I'm unable to test

dpsutton16:05:29

if anyone can evaluate (filter #(re-find #"target" %) (map str (.getURLs (java.lang.ClassLoader/getSystemClassLoader)))) in any boot project

plexus16:05:49

do you have an invocation that I can quickly test? I really don't know how to use boot... how do I generate an app and start a repl?

dpsutton16:05:17

there is a boot new command that sean has devloped

dpsutton16:05:44

boot -d boot/new new -t template-name -n project-name

dpsutton16:05:10

i'll bet you can just leave the template option out

plexus16:05:12

I'm suspecting it's leiningen... when running java -jar ep31.jar clojure.main from an uberjar it's not there

dpsutton16:05:10

(defn classloader-hierarchy
  "Returns a seq of classloaders, with the tip of the hierarchy first.
   Uses the current thread context ClassLoader as the tip ClassLoader
   if one is not provided."
  ([] (classloader-hierarchy (.. Thread currentThread getContextClassLoader)))
  ([tip]
    (->> tip
      (iterate #(.getParent %))
      (take-while boolean))))

dpsutton16:05:31

lein uses pomegranate for classloader management. is it possible that this is the offender right here?

plexus16:05:48

not there on boot, so it seems to be Leiningen. Thanks for the pointer, that gives me something to look into.

dpsutton16:05:17

i cloned that project and tried to add a failing test if applicable and I don't know how to jack into a project without a project file but only a pom file

dpsutton17:05:13

i guess you have to maven install your deps manually but i don't have maven on work computer as this is a .NET shop

stathissideris18:05:23

hello, does anyone know how to run a project via leiningen in non-headless mode? I want an icon etc to appear on my desktop

stathissideris18:05:03

I tried passing "-Djava.awt.headless=false" to :jvm-opts in project.clj but it had no effect

noisesmith18:05:37

@stathissideris I think you need a ^:replace on the :jvm-opts value for that to work

noisesmith18:05:57

the replace metadata tells it to replace the opts, not just add yours to the list

stathissideris18:05:07

@noisesmith thanks, I’ll give it a try!

stathissideris18:05:01

still no luck, but maybe I’m missing something

noisesmith18:05:12

are you looking at the args generated (eg. via ps ax)

Benjamin C19:05:40

is there a library which provides extension macros to clojure.test providing things like is-not and contains??

noisesmith19:05:56

honestly I just do that as (is (not ...)) and (is (contains? ...)) - I've never seen a library with such things

Benjamin C19:05:18

yeah that’s what i’ve been doing too.

jeff.terrell19:05:21

@benjamingramlich - Midje provides a variety of sugar for tests. Not sure about is-not specifically though. https://github.com/marick/Midje

Benjamin C19:05:58

i’m familiar with Midje. I guess what I want is more something like AssertJ that works seamlessly with clojure.test