Fork me on GitHub
#clojure
<
2018-08-01
>
theeternalpulse00:08:12

I made this function

(defn- apply-times
  [a-fn v n]
  (loop [res v
         i 0]
    (if (< i n)
      (recur (a-fn res) (inc i))
      res)))
to apply a function to a value x times and return the value itself, but I feel there is a canonical way to do this without creating a sequence?

theeternalpulse00:08:23

the alternative is something like (last (take 12 (iterate inc 0)))

hiredman00:08:27

((apply comp (repeat 12 inc)) 0)

theeternalpulse00:08:10

I guess I generally have an aversion to generating sequences of functions 😮

caleb.macdonaldblack00:08:02

Is there any function/macro that can create a map by just using the symbols as keys? I’m imagining a macro that might work like this: (->hash-map foo bar) would expand to {:foo foo :bar bar}

caleb.macdonaldblack00:08:41

I think I could make one but I just want to know if anyone has seen a macro that does this in clojure core

seancorfield00:08:21

No. But this has come up as a question occasionally before and I believe it comes down to a syntax in JS that effectively allows this convenience? Is that where you're coming from?

seancorfield00:08:36

(FWIW, I've almost never run into this situation where the work involved has been enough to make me yearn for a macro -- so I'm wondering how you're finding yourself in the position of wanting this...? Just curious)

caleb.macdonaldblack00:08:16

I think I know what syntax your talking about but I didn’t get the idea from that. I’m destructuring a map and only taking some keys. I might use select-keys for this sort of problem

seancorfield00:08:54

select-keys would be more idiomatic, I suspect. clojure.set/rename-keys can also be useful (if you mostly need the same-named keys but a few need to be renamed).

caleb.macdonaldblack00:08:36

Oh yea I forgot about that function. Not what I need in this instance as the keys are the same. Although I can recall times where I’ve wanted to do this

Mark Addleman00:08:03

@tbaldridge hi tim - are you thinking of picking up odin again? i really like the idea of a generic edn data query language and odin seemed like a great step in that direction

4
jjttjj01:08:06

@caleb.macdonaldblack are you aware of the :syms keyword for destructuring that can be used in place of the much more common :keys:

(let [{:syms [x y z]} {'x 1 'y 2 'z 3}]
      [x y z])
;=> [1 2 3]

caleb.macdonaldblack01:08:38

Ahh that’s quite handy. I’ve known of the :strs but not :syms

zaphodious04:08:05

Spec question - is there a way to get a minimal example from spec.gen?

seancorfield04:08:23

@achythlook Can you explain what you mean?

seancorfield04:08:13

s/exercise will generate values from a spec -- and the first few will be pretty minimal. Is that not what you're after?

zaphodious04:08:37

Not entirely. I'm aiming to generate a fairly complex entity map with several colls, and s/exercise spits out fairly large examples.

zaphodious04:08:57

For reference, here's the file where I've defined the specs in question. https://github.com/Zaphodious/yushan/blob/master/src/com/blakwurm/lytek/spec.cljc

seancorfield04:08:45

But the first example in the output of s/exercise is going to be fairly minimal, yes?

zaphodious04:08:48

Not in some tests that I've done here.

(first (s/exercise :lytek/solar))
spits out entities with various vectors of 20ish elements.

seancorfield04:08:35

Since that's driven by (pseudo) random generation and usually starts from near-minimal cases, I suspect you'd have to write custom generators to have more control over it... but I guess I'd ask, why do you want minimal cases? As long as they conform, why does it matter?

zaphodious04:08:38

I'm building an API where people will be able to make a "new" entity of various types and subtypes. I was hoping to use this to make said entities rather then maintaining fresh examples by hand.

zaphodious04:08:56

No major loss, as I can just run s/explain on my hand-maintained entities 🤷

zaphodious04:08:58

Thanks anyway!

Kart09:08:35

Hi everyone, I need some help deploying my project to clojars

Kart09:08:42

I used

lein deploy clojars
but I get the error
gpg: signing failed: Inappropriate ioctl for device

andy.fingerhut10:08:41

Google searches for unfamiliar error message can sometimes turn up help. In this case, I found this page that might be helpful to you: https://github.com/keybase/keybase-issues/issues/2798

txe12:08:04

Hi, I was trying with https://github.com/relevance/labrepl but got into issues related with insecure HTTP warning when run $ lein deps is it me or the site itself is deprecated? Would anyone know to tell?

andy.fingerhut16:08:31

@U0U0HFT3J I had a similar problem last night with Leininingen version 2.7.1 and 2.8.1 commands when running with Oracle JDK 1.8.0_171. I installed Oracle JDK 1.8.0_181 and the problem went away. I do not know the cause of the problem, or the reason why updating my JDK made it stop.

manutter5112:08:47

Interesting, I thought it might be the issue where leiningen 2.8 does more rigorous checking of security certificates, but I just downloaded the labrepl repo and ran lein deps with no problems or warnings.

txe12:08:52

I got Leiningen 2.8.1 on Java 1.8.0_181 OpenJDK 64-Bit Server VM and still got the issue

txe12:08:46

I also have that warning if doing '$ lein -v' being in the repo dir

txe13:08:48

to check the version I had to type '$ lein -v' at ~/$

lilactown14:08:11

I’m running into kind of an annoying thing, looking for some help

lilactown14:08:30

I’m trying to convert a vector of lein dep coords into a map for deps.edn

lilactown14:08:26

I decided to write a simple fn/macro to do this, however, instead of getting something like:

(to-deps [org.clojure/clojure "1.9.0"])
=> {org.clojure/clojure {:mvn/version "1.9.0"}}
when I convert it to a map I get something like:
(to-deps [org.clojure/clojure "1.9.0"])
=> #:org.clojure{clojure #:mvn{:version "1.9.0"}}

lilactown14:08:29

this is my current naive implementation:

(defmacro to-deps [[sym version]]
  `{'~sym {:mvn/version ~version}})

lilactown14:08:35

I figured this would be easy 😛

lilactown14:08:57

okay, it’s dumb but I guess this is solved by putting another value in the map that isn’t the same namespace:

(merge (to-deps [org.clojure/clojure "1.9.0"])
       (to-deps [asdf/jkl "1.12.3"]))
=> {org.clojure/clojure #:mvn{:version "1.9.0"}, asdf/jkl #:mvn{:version "1.12.3"}}

lilactown14:08:36

so I can just add a dummy element to the map containing :mvn/version as well :face_with_rolling_eyes: and find and replace

lilactown14:08:23

are there any resources on AOT compiling and packing an uberjar with deps.edn?

ghadi14:08:23

our tool depstar will make an uberjar but not AOT compiled

Alex Miller (Clojure team)14:08:33

@lilactown those maps are the same map, this is just printing

ghadi14:08:52

they are not the same maps, one has keywords and one has symbols

Alex Miller (Clojure team)14:08:27

namespace map syntax works for symbols too

ghadi14:08:01

you can get the keywords to print the classic way by doing (set! *print-namespace-maps* false)

🎉 4
Alex Miller (Clojure team)14:08:02

{org.clojure/clojure {:mvn/version "1.9.0"}} is same as #:org.clojure{clojure #:mvn{:version "1.9.0"}}

ghadi14:08:29

org.clojure/clojure is a symbol on the left but there is a keyword on the right

ghadi14:08:39

the mvn part is the same

ghadi14:08:07

ummmm maybe my coffee isn't working

Alex Miller (Clojure team)15:08:21

what I said above is correct

ghadi15:08:54

Yup, thanks for catching. Too bad the namespace map syntax biases your eyes towards keywords

lilactown14:08:29

yeah, for my case the literal output was important because my thinking was, “Oh I have like 20 leiningen dependencies. I’ll just write a quick clojure function/macro to convert it to deps.edn format and Eval-replace in my deps.edn”

lilactown14:08:25

okay, I looked at juxt/pack and depstar and didn’t see support for AOT compilation. it looks like badigeon might?

ghadi14:08:18

you can do it with depstar with a manual step if you compile and then use jar -u to put the AOT output back into the jar

ghadi15:08:10

All depstar does it tar up the dependencies.

lilactown15:08:28

by compile you mean with javac? </jvm-noob>

ghadi15:08:45

no clojure.core/compile

ghadi15:08:54

that's the heart of AOT compilation

ghadi15:08:42

(set! *compile-path* "outputdir") and make sure outputdir is on the classpath

ghadi15:08:55

then from the repl call compile on the namespace you want to compile

lilactown15:08:35

okay so if I understand correctly, the order of operations is: 1. build uberjar (no AOT) 2. start uberjar (no AOT) 3. run clojure.core/compile 4. repack uberjar? 5. deploy uberjar (AOT)

lilactown15:08:18

okay, great. thank you for the help!

ghadi15:08:18

also beware limitations of AOT

lilactown15:08:33

I’m migrating an app that was already AOT compiling using leiningen - so if this basically does what lein uberjar does then I should be 👍

thiru15:08:26

Is there a recommended version of Java I should be using with Clojure? I know 1.8+ is required but I've heard there are potential issues with the latest version. I'm currently using OpenJDK 10 (Linux) and I get a reflection warning when I first connect over nREPL but haven't noticed anything else weird. But maybe there are other issues I may/likely come across in production?

jumar20:08:51

@thiru0130 depending on your tools you may hit some issues, e.g. with cljr-refactor and/or pomegranate (dynamic loading of dependencies).

thiru02:08:55

thanks for the heads up @U06BE1L6T .. I'm not using those.. I think I'll stick with v10 until it bites me 😕

johnj15:08:59

could be a dep, but if you have to ask I think is just better to stick with java 8

ghadi16:08:09

I use OpenJDK 10 w CIDER/nREPL. no reflection warnings:

➜  git:(production) ✗ clj -A:dev:nrepl - <<EOM
(require 'cider-nrepl.main)
(cider-nrepl.main/init ["cider.nrepl/cider-middleware"])
EOM

nREPL server started on port 42585 on host localhost - 

ghadi16:08:41

I would avoid Java 9 because it's sunsetted and CA cert bundle issues -- but either 8 or 10 should be fine. (Clojure 1.10 is dropping support for JDK <8)

thiru16:08:32

Thanks @ghadi - I guess I'll stick with 10

johnj16:08:22

problems might start to creep up when using third party libs not clojure itself

ghadi16:08:53

a helpful JVM 9+ flag to see what is being naughty is: --illegal-access=debug -- You'll get a stacktrace when something does illegal reflection (no exception thrown, but a printed trace)

johnj16:08:54

some libs use some very old deps

bwstearns16:08:19

Anyone got a good name for a function that behaves like this? Takes two vecs of things, returns a map where the keys are the first vec and the vals are whether or not that key is present in the second vec. so far I’m thinking something like isin-map or zipmap-membership but I’m not super sold.

(foo [1 2 3] [1])
{1 true, 2 false, 3 false}

hiredman16:08:46

clojure.set/intersection

dpsutton16:08:08

or just turn the second vector into a set

dpsutton16:08:28

it will behave identically as your function. O(1) membership check

bwstearns16:08:31

@hiredman I’m using intersection in the function but I need the falsey values in the map as well. intersection will just give me the truthy values

hiredman16:08:30

why do you think you need the false values?

bwstearns16:08:18

The frontend needs them.

bwstearns16:08:21

the set of things is a dynamic list of options, so the front end doesn’t know ahead of time which options are available so it needs to be able to show the unselected things in order for a user to select them.

thiru17:08:57

@ghadi yes the "illegal access" warning is what I see now. No big deal though I guess

justinlee17:08:51

in terms of style, is it normal to have a deftype constructor with 8 positional parameters? I was just looking at the reagent code and I see (->Reaction f nil true false nil nil nil nil), which is incredibly hard to read (to my eyes), but I wonder if I’m missing something and how else it should have been done

justinlee17:08:03

I would have been inclined to pass an options map, but I feel like I’m missing something

noisesmith17:08:12

deftype doesn't have a map constructor, but making a simple wrapper for the positional constructor is easy, and probably a good idea once you have more than 5 args

👍 4
thiru18:08:30

Anyone know of a library to connect to an nREPL server using clj CLI? I.e. not leiningen/boot

noisesmith18:08:19

the clojure.tools.nrepl project has client code, you can use that via clj cli

noisesmith18:08:51

also there's grenchman if what you want is a low overhead fast startup ready to go nrepl client (it's an ocaml program, but works with a clojure server just fine) https://github.com/technomancy/grenchman

thiru18:08:23

thanks @noisesmith - I was hoping there would be something more built out like running lein repl :connect

thiru18:08:15

.. but without using leiningen

noisesmith18:08:43

do you need it to be a clojure process? because if no grenchman just works

thiru18:08:40

hmm I want to be running a clojure repl

noisesmith18:08:53

you get a connection to the server

noisesmith18:08:56

it's clojure

thiru18:08:58

can grenchman get me into that without using leiningen?

noisesmith18:08:05

it's just that the client program is written in ocaml

noisesmith18:08:20

right, it's a very small ocaml program that connects to clojure nrepl as a client

johnj18:08:25

@thiru0130 your editor may have a nrepl client

noisesmith18:08:31

there's that too

thiru18:08:50

hmm ok let me look at grenchman closer

noisesmith18:08:55

but grenchman is most certainly lighter weight and faster to start up than your editor :D

thiru18:08:14

@lockdown- thanks but what I want really is just a simple clojure REPL separate from any editor but connected to an existing nREPL server. I want to use this to then start rebel-readline

noisesmith18:08:05

doesn't rebel-readline need to directly control your terminal though?

noisesmith18:08:14

maybe I don't understand what it's doing

thiru18:08:16

yes that's the thing

thiru18:08:39

so it looks like grenchman is using leiningen underneath so it won't work for me unfortunately

noisesmith18:08:41

in that case you would need to build something yourself, connecting rebl-readline to an nrepl client

noisesmith18:08:00

no, it can talk to any nrepl server - the lein part is optional

thiru18:08:16

yes except that I think I lack the clojure skill to do this point 🙂

noisesmith18:08:21

(that's intended as the main usage, but lein isn't needed for your use case)

cjsauer18:08:03

@thiru0130 perhaps you could come up with a clojure command-line invocation to achieve this...something like:

clojure -Sdeps '{:deps {nrepl ...}}' -e '(require 'nrepl) (nrepl/connect-to-server)'
Obviously those deps and functions need massaging, but something like that might be able to "bootstrap" into a more sophisticated environment.

noisesmith18:08:28

I really think having a clojure process that owns the terminal is the needed starting point for using rebel-readline, so either you wait for someone else to hook that up using clj and tools.nrepl client, or do it yourself

noisesmith18:08:57

@cjsauer sure but does that hook up stdin to the remote repl?

thiru18:08:01

thanks @cjsauer - but I think @noisesmith is right.. this seems to the be the hard bit (for me anyway).. handling edge cases, timeouts, exceptions etc.

cjsauer18:08:11

Hm yeah...I see the issue..

noisesmith18:08:10

what @thiru0130 wants is the glue that connects rebel-readline to a tty + stdin and connects it to a remote nrepl process instead of clojure in that same vm

noisesmith18:08:34

the pieces all exist, but hooking it up isn't quite just legos

cjsauer18:08:36

That's unfortunate as it seems almost fundamental...something like "sub-repls". Does the newer socket repl ease any pain? Or is this not at all nrepl specific?

cjsauer18:08:19

It looks like you can get a very stripped rebel-readline working inside an arbitrary REPL: https://github.com/bhauman/rebel-readline/blob/master/rebel-readline/src/rebel_readline/clojure/service/simple.clj

noisesmith18:08:42

right, that's still talking to your in-vm clojure and not the remote though

noisesmith18:08:17

@lockdown- they already have a remote, they need to talk to it

cjsauer18:08:12

Ah duh...I see what you mean by "glue" then. Some kind of modified I/O

johnj18:08:28

@noisesmith yeah, in that link, just below it says how to embed the client

noisesmith18:08:57

right, and if you read further it shows the protocol etc.

eraserhd18:08:02

Is pr-str known to be especially slow?

thiru18:08:07

bhauman is going to get to supporting nrepl eventually.. maybe just wait.. or try it myself 😮

skrat19:08:51

I'm kind of lost in interceptors, I would like to log response status code and duration, how can I do that? (pedestal)

cjsauer19:08:47

@skrat might have better luck over in #pedestal