Fork me on GitHub
#clojure
<
2019-07-10
>
pinkfrog03:07:56

how do you add dependencies to a running repl?

pinkfrog03:07:28

or is it possible to tell lein to use all the jars in .m2 as dependencies ?

seancorfield03:07:52

@i Boot lets you add dependencies to a running REPL. CLI/`deps.edn` allows that as well, if you use the add-lib branch of tools.deps.

seancorfield03:07:19

I'm not sure if you can do it out of the box with Leiningen...

Benny kach05:07:02

Hi guys, there is a library or home-made fn that i can merge n collections by ratio? I mean if i have [1 2 3] and [a b] [z x y] and ratios {:first-coll 1 :second-coll 2 :third-coll 3} so the result should look like (or something similar to) [z x y a b 1 2 3]

the2bears06:07:28

@bennyk, I can't tell from that example what you need. What do the ratio values mean? What does it mean that :first-coll is 1 and :second-coll is 2? I'm looking for a pattern in the result and my brain is too tired 😅

Benny kach06:07:51

haha yea sorry for the bad explanation. The function should get N collection and N ratios. It construct 1 new collection. To describe better here is an example: given collection-a: [1 2 3] and collection-b: [a b] and collection-c: [z x y] as input collections, a number Q and {:first-coll 1 :second-coll 2 :third-coll 3} The result collection will contain all the items from the given collections, but ordered like this: construct first Q elements by taking 3 elements from the third collection, 2 from second collection and 1 from third collection. Then construct the next Q items. If for example all the items were already taken from the 2 first collections (collection-a and collection-b) it will just add the items that left from the third collection-c. The end result will look like: [ z x y a b 1 2 3 ]

Benny kach06:07:16

For [1 2 3] and [a b] [z x y w u v] and ratios {:first-coll 1 :second-coll 2 :third-coll 3} => [ z x y a b 1 w u v 2 3 ]

ivana10:07:37

Hello& I'm playing with Ring and trying to send some edn structures between front and back and the opposite way. I believed in Rich's isomorphysm, but all edn<->json converters/middlewares I tried made me disappointed - i.e. on

{1 1,
 "2" "2",
 :a :a,
 [1 "2" :a] [1 "2" :a],
 {1 1, "2" "2", :a :a, [1 "2" :a] [1 "2" :a]}
 {1 1, "2" "2", :a :a, [1 "2" :a] [1 "2" :a]}}
in body on back side I got
{
  "1": 1,
  "2": "2",
  "a": "a",
  "[1 \"2\" :a]": [
    1,
    "2",
    "a"
  ],
  "{1 1, \"2\" \"2\", :a :a, [1 \"2\" :a] [1 \"2\" :a]}": {
    "1": 1,
    "2": "2",
    "a": "a",
    "[1 \"2\" :a]": [
      1,
      "2",
      "a"
    ]
  }
}
on front side - it stringifyes all keywords and all key types! Can a achieve a real 1-to1 convertation anyway? I know, that json have not keywords, but I it can be a convention that any string starts with : have to convert to keyword

andy.fingerhut10:07:42

I do not have much experience with using it myself, but have you tried Transit? https://github.com/cognitect/transit-clj

4
ivana10:07:28

Ok, thanks, I'l see.

vlaaad10:07:46

@ivana have you seen transit?

ivana10:07:26

@vlaaad not yet, thanks, I'l see it

vlaaad10:07:32

it's a data format that works over json, but serializes all clojure data structures preserving their types

ivana10:07:02

Sounds promising, I was ready to write my own custom bicycle, but it seems that there is a reason to look at it first 🙂

ivana13:07:57

For testing needs it was easier for me to make some quick and dirty encoder/decoder for transition edn thru json 🙂

(defn encode-edn [x]
  (cond
    (keyword? x) (str x)
    (map? x) {"map" (map encode-edn x)}
    (coll? x) (mapv encode-edn x)
    :else x))

(defn decode-edn [x]
  (cond
    (string? x) (if (str/starts-with? x ":") (keyword (subs x 1)) x)
    (map? x) (->> (get x "map") decode-edn (into {}))
    (coll? x) (mapv decode-edn x)
    :else x))

vlaaad13:07:50

why not just pr-str/`clojure.edn/read-string`?

👍 8
ivana13:07:43

Mmm, let me test it

macrobartfast13:07:24

when making a post from clj-http I am getting an Unhandled sun.security.provider.certpath.SunCertPathBuilderException unable to find valid certification path to requested target any suggestions of where to start?

Michael Griffiths13:07:28

I’ve debugged this in the past with the JVM option -Djavax.net.debug=all

Michael Griffiths13:07:26

In my case I needed to add the relevant certificates to the JDK Truststore using keytool

jumar05:07:10

Yeah, most likely the server isn't using a trusted certificate. Check with browser or openssl if that's the case. If they say the certificate is valid they might be a mismatch between what Java considers a valid certificate and what browser/OS considers a valid certificate. You may need to import that specific certificate into the java keystore as cichli suggested. In some cases, there might be problems with intermediate certificates.

macrobartfast13:07:06

curl works to the same thing.

ivana13:07:07

@vlaaad thanks, it works nice and I think faster, than construction of temp clojure structures. And I do not need json (with its limitations) anywhere. Seems, that only 2 special points - this string can be readed only with cljs clients (it is not a common json api), and it can not be structured in browser developer tools

theeternalpulse16:07:01

Anyone here have much experience with integrant? I posted a q on #integrant but not sure if the channel is in the view of many users.

the2bears16:07:07

@bennyk, this is a pretty specialized use-case, so there's no library fn. I'd take the approach of taking each collection, and partition-all by its respective "ratio". (partition-all 3 [1 2 3 4 5 6]) yields ((1 2 3) (4 5 6)). You can then recursively concat the elements of the partitioned collections together.

macrobartfast17:07:44

currently using clojure.shell/sh inside the code to curl it all up, which seems like quite an anti-pattern (and not very production friendly), but resolving cert issues in clojure is definitely testing my knowledge.

noisesmith17:07:45

@macrobartfast there's a shell command to add a trusted cert for a jvm, that's probably what you want here

noisesmith17:07:39

keytool -import ... perhaps

macrobartfast17:07:03

thanks! I'll take a look.

macrobartfast17:07:26

in this case it's someone else's server, so don't know if that will help...

noisesmith17:07:34

also, depending on OS, there's utilities to keep the jvm certs up to date via the package manager

macrobartfast17:07:54

and since curl seems to work, I'm guessing they have things right... but my knowledge of cert stuff is pretty weak.

noisesmith17:07:14

@macrobartfast the import works with any cert - the example is your own self-signed cert, but the same import works in any case where you know a specific cert should be trusted but it doesn't have a global root

noisesmith17:07:28

it could be you need to make your OS update java's certs

macrobartfast17:07:57

ah ok... so I would find out what the cert is from the vendor.

macrobartfast17:07:29

lol... I'm really tipping my hand here.

noisesmith17:07:34

even curl can get you the cert to add (or openssl) iirc

noisesmith17:07:54

> connects to the desired website and pipes the certificate in PEM format on to another openssl command that reads and parses the details

lwhorton17:07:41

just got the conj email, exciting!

dpsutton18:07:26

Where’s the location this year? I haven’t gotten one yet

andy.fingerhut18:07:42

Durham, North Carolina

dpsutton18:07:40

Thanks Andy

ag20:07:31

I need a macro where I use another macro inside. Namely I need a macro that takes a params map and a body, and does with-redefs on some function based on params then run body inside, but I’m struggling with all those splicing/unsplicing rules. Can someone show me a similar example please.

noisesmith20:07:00

I don't have a specific example, but the main things that helped me with this sort of thing were: 1) understanding that splicing/ quoting etc. are not macro features, they are list construction features 2) the goal of a macro is to construct the code you want compiled as a list - whether your list happens to contain a macro invocation vs. a function call shouldn't change things much

ag20:07:59

So I need something like this:

(defmacro with-all-redefs
    [{:keys [agreement-map
             certificate-map] & body]
  `(let [doc-pkgs (list agreement-map certificate-map)]
    (with-redefs [db/get-project (constantly doc-pkgs)]
      ~@body)))

noisesmith20:07:33

doc-pkgs is invalid as a binding name inside `

ag20:07:49

right, so how do I make it right?

noisesmith20:07:50

but for your case here, replacing it with doc-pkgs# suffices

noisesmith20:07:09

(that's an auto-gensymed local, all uses are guaranteed to use the same symbol)

ag20:07:37

okay I’ve fixed that, but I think still missing something macroexpand creates strange list of things

ag20:07:45

maybe that’s what supposed to happen, I dunno. I’m gonna test. Thank you @U051SS2EU

noisesmith20:07:31

the expansion of ` (especially with ~@) tends to look very weird

ag20:07:40

oh… my.. I’m so stupid… I was macroexpanding on the macro definition… picard-facepalm

ag20:07:52

how do I refer to auto-gensymed local from the body?

noisesmith20:07:00

it's the same

noisesmith20:07:10

(let [foo# ...] (frob foo#))

ag20:07:24

oh… okay!

noisesmith20:07:29

the two uses of foo# are guaranteed too expand to the same auto-generated symbol

ag20:07:23

now I’m struggling with destructuring… how do you make a macro that take a map and destructure it?

noisesmith20:07:31

I think the easiest way is to use the normal (non :keys) map destructure

noisesmith20:07:42

{foo# :foo bar# :bar}

noisesmith20:07:18

oh, but your :keys destructure is outside the ` block, so it should be fine anyway

ag20:07:49

why this not working:

(defmacro with-all-redefs
  [params & body]
  `(let [{:keys [foo]} ~@params]
     (prn foo)))
     
(with-all-redefs
   {:foo "one"})

noisesmith20:07:52

oh that's not what you had before, you do need the alternative destructure for that

noisesmith20:07:50

but if it's possible to move the let binding outside the syntax quote block that's even better

ag20:07:13

okay, let me try that…

ag20:07:23

damn… macros are really confusing

noisesmith20:07:26

also that ~@params is surely wrong

noisesmith20:07:43

cmd)user=> (defmacro with-all-redefs
               [params & body]
               `(let [{foo# :foo} ~params]
                  (prn foo#)))
#'user/with-all-redefs
(ins)user=> (with-all-redefs {:foo "foo"})
"foo"
nil

ag20:07:17

… trying

ag20:07:47

holy shit…. I got it… Thanks man! this is so cool… you saved me hours of work!

theeternalpulse01:07:34

Most of the macros I create of are hours of work 🙂

theeternalpulse01:07:44

but those sweet sweet minutes of work it saves lol

elena.poot22:07:49

In a multimethod, is it possible to override the dispatch function and call a specific method? I'd like to create a new method that simply calls one of the other defined methods. (I need to do this because there's a different method that takes priority if I don't. Also, the multimethod is a library function so I can't change it.)

hiredman22:07:31

you can reach into the multimethod and pull out the function for a given dispatch value and just invoke it directly

elena.poot22:07:59

Exactly what I want! What's the syntax for that?

hiredman22:07:28

it isn't syntax, you use get-method, pass it the multimethod and the dispatch value to get the function from the multimethod, then pass it whatever arguments

elena.poot22:07:42

awesome, thanks!

elena.poot22:07:05

Yep, solved my problem perfectly. Thanks again. I didn't know about get-method, and apparently was using the wrong search terms. 🙂

elena.poot22:07:02

And in case anyone else ever hits this: if you pass a SQLException to clojure.data.java/from-java, it'll overflow the stack, because SQLException implements Iterable and returns itself as the first item of the iteration. Can be fixed with: (defmethod from-java java.sql.SQLException [^Object instance] ((get-method from-java :default) instance))

andy.fingerhut22:07:29

Might be good to put that in a ticket for the clojure.data library if you are willing. I would be a little bit surprised if the maintainers want to change the lib for that case, but having it documented near the library might be useful.

elena.poot22:07:03

I'm certainly willing if you think it'd be useful

andy.fingerhut22:07:42

For all I know, there might be dozens of such weird cases for various Java classes, and trying to collect them all in one place would be a nightmare 🙂

elena.poot22:07:09

Yeah. I consider this class somewhat ill-behaved. There are getNextException/setNextException methods, but if you access it as an iterator it follows that chain, starting with itself. Nothing that tries to walk the class recursively is going to work. My one-liner ignores the Iterator behavior, but it'll still capture the whole chain of exceptions through the getNextException getter. So that solution is quite specific to this one class.

elena.poot22:07:59

How does one file a ticket for that project?

andy.fingerhut22:07:21

The link to do so changed in the past month or so -- let me look for the updated one ...

andy.fingerhut22:07:23

Going to http://clojure.org and clicking the DEV link near the top right takes you to a page with lots of instructions, including a "If you simply need to file a bug, you can do so" link under the "Becoming a Contributor" heading.

andy.fingerhut22:07:58

That link lets anyone create a bug report, which someone (likely Alex Miller) will decide where it goes.

elena.poot22:07:11

awesome, thanks

Graham Seyffert23:07:17

Hey folks, I need some more JDK 11 help here

Graham Seyffert23:07:11

I’m getting these kinds of errors on JDK 11, but not JDK 8 -

java.lang.NoClassDefFoundError
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)

ghadi23:07:36

likely...

Graham Seyffert23:07:45

This error is being thrown when trying to load a function that’s bound in a let

ghadi23:07:45

you've compiled stuff on JDK8 that reflects

Graham Seyffert23:07:03

it’s compiled on JDK 8 right now, yes

Graham Seyffert23:07:12

This isn’t reproducible on my local machine though

ghadi23:07:13

you're eliding some critical stack traces

ghadi23:07:44

there's probably something beneath those traces that will clue you towards what isn't being found

Graham Seyffert23:07:02

I know what isn’t being found, but I can’t figure out why it isn’t being found

ghadi23:07:15

is clojure.lang.Reflector in the stack trace?

Graham Seyffert23:07:33

Nope, only jdk internal reflection references

Graham Seyffert23:07:43

I can get the full stack here, but I have to clean up some names before that

ghadi23:07:11

@gseyffert the AOT compiled stuff on JDK 8 is probably calling a method on a class that either no longer exists or was renamed on JDK11, or has been made module private in JDK11

Graham Seyffert23:07:34

Actually in this case it’s pulling a function off of a record

Graham Seyffert23:07:09

sorry still cleaning this stack

ghadi23:07:31

the function is a protocol method implemented by the record? or a fn stored in a record's field?

Graham Seyffert23:07:07

the latter I believe.

Graham Seyffert23:07:22

accessed via (:a-keyword a-record)

ghadi23:07:39

do you get the error accessing the fn on the defrecord, or after accessing when you try to call it?

Graham Seyffert23:07:38

OK here’s the clean stack -

ghadi23:07:24

there's an inner function in your_file_name.clj:243, which is being passed to r/fold

Graham Seyffert23:07:27

The flow is basically -

(let [a-fn (:some-kw a-record)
      ...
      reduce-fn (bound-fn
                  ([] {})
                  ([m itm]
                   ...
                   (if (or (nil? a-fn) (a-fn some args)) ;; throws here
                     ...
                     )
                   )
                  )
      ]
  (fold 4 merge reduce-fn a-coll)
  )

ghadi23:07:32

possibly an inner inner function

ghadi23:07:01

does that inner function use type hints/interop?

Graham Seyffert23:07:44

it does in some cases, but this will throw for record instances that don’t even have :some-kw defined (just nil)

noisesmith23:07:16

I'd expect that to throw

Graham Seyffert23:07:49

In my code example above it’s more like (if (and a-fn (a-fn some args)) ...)

Graham Seyffert23:07:02

or rather, it’s

Graham Seyffert23:07:28

(if (or (nil? a-fn) (a-fn args)) ...)

Graham Seyffert23:07:12

So we aren’t trying to call nil

Graham Seyffert23:07:38

I attached a remote debugger as well to repro and indeed (nil? a-fn) resolved as true

Graham Seyffert23:07:56

it’s messing me up because we have another similar function that uses the same pattern, except w/out binding a function from a record, and it works just fine

ghadi23:07:32

/**
     * Returns a rethrowable exception for this task, if available.
     * To provide accurate stack traces, if the exception was not
     * thrown by the current thread, we try to create a new exception
     * of the same type as the one thrown, but with the recorded
     * exception as its cause. If there is no such constructor, we
     * instead try to use a no-arg constructor, followed by initCause,
     * to the same effect. If none of these apply, or any fail due to
     * other exceptions, we return the recorded exception, which is
     * still correct, although it may contain a misleading stack
     * trace.
     *
     * @return the exception, or null if none
     */

ghadi23:07:52

^^^ at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:603)

ghadi23:07:32

at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
    at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:603)
    at java.base/java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:678)
    at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:722)
    at java.base/java.util.concurrent.ForkJoinPool.invoke(ForkJoinPool.java:2423)
    at clojure.core.reducers$fjinvoke.invokeStatic(reducers.clj:30)
    at clojure.core.reducers$foldvec.invokeStatic(reducers.clj:306)
notice you're in a sad path already

ghadi23:07:53

seems like your task failed before this

ghadi23:07:00

and FJ is trying to clean up

ghadi23:07:06

unhelpfully

Graham Seyffert23:07:21

I hear you, but it’s also the case that some instances this works fine, and on other instances it doesn’t

Graham Seyffert23:07:33

Restarting helps, but then over time the errors reappear

ghadi23:07:00

"some instances this works fine" -- which instance do you mean?

ghadi23:07:10

machine, object instance, execution run?

Graham Seyffert23:07:22

virtual machine, same host

Graham Seyffert23:07:52

So 2 JVMs running on the same host, one will throw this error and the other won’t

Graham Seyffert23:07:02

And once it starts throwing, it doesn’t stop

ghadi23:07:02

the class it can't find is one of yours (clojure)?

ghadi23:07:42

do you have an accessible REPL on the problematic machine?

ghadi23:07:56

was wondering if there is a classloader visibility difference...

Graham Seyffert23:07:42

It does seem to be some issue with the classloader... besides JDK 11, the only correlation I’ve been able to find is just amount of traffic that instance has taken since starting up

Graham Seyffert23:07:34

On this machine I might have a repl. I can look in a few minutes

ghadi23:07:05

is the bound-fn necessary?

ghadi23:07:50

I wonder if the very first time the offending class gets loaded is within a context in which it cannot initialize

ghadi23:07:11

and that just happens to be within the FJPool

Graham Seyffert23:07:17

That’s a sore point haha. I wish it wasn’t but unfortunately it is

Graham Seyffert23:07:34

Much of our stack is ancient and still uses threadlocals (!!!)

ghadi23:07:38

I don't mind infrequent thread locals :)

ghadi23:07:03

(one of the things the bound-fn might be conveying is a classloader)

Graham Seyffert23:07:09

Hence the usage of bound-fn

Graham Seyffert23:07:20

Hmm that is a thought!

ghadi23:07:31

like Compiler/LOADER