Fork me on GitHub
#clojure
<
2019-07-17
>
Ramzi01:07:48

whats wrong with this function

Ramzi01:07:52

(defn string-substring-after-first-instance-of-character[character string] (subs string (.indexOf character string) (- 1 (.-length string)))

andy.fingerhut01:07:25

do you want subs to return all the way to the end of the string?

dpsutton01:07:31

look at the error. (- 1 1000) is a negative number

andy.fingerhut01:07:33

If so, the 3rd arg is unnecessary

Ramzi01:07:57

andy yes, thx

andy.fingerhut01:07:17

also what dpsutton said

dpsutton01:07:55

also this is the error i get > StringIndexOutOfBoundsException begin 1, end -3, length 3 java.lang.String.checkBoundsBeginEnd (String.java:3319) which is pretty good i think

dpsutton01:07:18

the error messages are verbose but very informative

dpsutton01:07:34

er, verbose isn't right but you get my drift i think

noisesmith01:07:15

that's a particularly good one - it even shows the index asked for

Alex Miller (Clojure team)02:07:02

does that code even work? length is not a public field of String, it's a method

Alex Miller (Clojure team)02:07:32

so should be .length, not .-length

noisesmith02:07:04

also the parameter name "character" is misleading

noisesmith02:07:09

and the args to indexOf are reversed in order

vlaaad07:07:08

is it okay to extend protocol to 2 classes belonging to same hierarchy? If Child extends Parent, and I extend protocol to both Child and Parent, and I invoke protocol function on an instance of Child, is it guaranteed Child's extension will be called, and not Parent's?

jumar08:07:57

That should work. The basic case is that the "parent" is java.lang.Object

(defprotocol testik
  (printik [x]))
(extend-protocol testik
  String
  (printik [x] (println "String: " x))
  Object
  (printik [x] (println x))
    )

(printik "hello")

Alex Miller (Clojure team)12:07:38

Yes, the closest ancestor is preferred

👍 8
Andrew13:07:36

Anyone used Jib (https://github.com/GoogleContainerTools/jib) with Leiningen to build containers with Clojure apps?

aisamu13:07:12

Not lein, but worth noting that pack.alpha recently added support for this: https://github.com/juxt/pack.alpha/pull/42

Andrew13:07:28

Thanks, I'd seen that, was wondering if anyone had done similar work with Leiningen. I'll have a look at the pack.alpha implementation.

bartuka15:07:17

hey guys, do you know any code static analysis tool that handles Clojure well? (https://www.sonarqube.org/) Sonarqube is not working fine for us here. Many incompatibilities with eastwood, nvd and cloverage to work around

lukasz15:07:16

@iagwanderson the closest I ever got was to codeclimate + coverage tracking with cloverage and codeclimate-kibit engine. I

lukasz15:07:46

I'm now looking into creating a code climate engine for clj-kondo and figuring out how I can merge the two into one reporter for CC

aw_yeah 4
bartuka16:07:22

@lukaszkorecki I would like to test the your setup here. For now, I am looking at cloverage and eastwood integrations. Do you had to do specific workarounds to make it work?

Joe Lane16:07:51

@iagwanderson What functionality in specific are you desiring from "static analysis"? I make tools at home for this kind of stuff sometimes and I'm interested in the usecase you're desiring.

Joe Lane16:07:12

(pure curiosity)

lukasz16:07:43

@iagwanderson codeclimate-kibit repo is itself plugged into codeclimate (both kibit and cloverage) https://github.com/lukaszkorecki/codeclimate-kibit - so you can see the setup there. One thing that's out of date is coverage tracking, as there were issues around lcov format but are now fixed in latest cloverage version. Also, this repo will soon migrate to codeclimate's own org giving Clojure somewhat a first-class support in code climate

lukasz16:07:27

(I'm not affiliated with CodeClimate btw, I just needed things to work as our team has 20+ Clojure repos , so we need automated tools for code linting and test coverage)

lukasz16:07:34

(but CC did send me a t-shirt ;-))

😎 4
bartuka16:07:41

this view is from sonarqube and I find it just perfect. The Vulnerabilities are provided by lein-nvd, code smells and code duplication are provided by eastwood and other linters, coverage from cloverage

Joe Lane16:07:23

Cool, thanks

bartuka16:07:43

@joe.lane the problem right now are the integrations of these plugins with the sonarqube job

bartuka16:07:24

@lukaszkorecki thanks, I will try CC here, that's probably good enough for my use case

lukasz16:07:36

let me update the gist to what we have now in our projects

ghadi16:07:11

can someone talk about the things they are doing with static analysis (besides vulnerability scanning) ?

bartuka16:07:58

@ghadi one thing that is very nice in some python projects is to analyse code complexity.

ghadi16:07:13

yeah -- but for clojure specifically

bartuka16:07:29

look at this amazing report from sonarqube with python. I would love to see something like this to clojure

bartuka16:07:40

eastwood is the most complete for me right now

ghadi16:07:10

I used to use a bunch of coverage stuff for python -- but python cyclomatic complexity is different than clojure's

dpsutton16:07:15

@ghadi my coworkers heavily rely on clojure-lsp. not sure if that falls under the notion of static analysis discussed right now

dpsutton16:07:58

they probably only connect to nrepl once a week and do all development "statically" in that sense.

noisesmith16:07:55

to the extent that eastwood is static analysis: we use it because it finds bugs in a microservice in code paths that would otherwise require complex scaffolding or a full running system to find

noisesmith16:07:02

arguably we wouldn't need it if we designed the microservice properly with testable code, but there's a lot of institutional friction to rewriting code to be more testable (and I have seen this in every other workplace as well)

Joe Lane16:07:15

I'm not sure if I'd call it "static" analysis, but I've been off and on working on a tool called REDEX which identifies Reducible Expressions (in the lambda calculus sense) and suggests how to refactor them into their minimal form. It can parse clojure code from files, but it also has a repl. Uses logic programming, inspired by kibit but has heavily departed from it. I'm hesitant to call it static because it works both statically and at runtime with information available at runtime.

lukasz16:07:31

@iagwanderson here's the updated gist, https://gist.github.com/lukaszkorecki/60093e57cbb4b178547e4a7ff23c703d - I didn't test it but it's almost the same as our internal ones (we add cloverage as a plugin in project.clj so we don't have to download lein-cloverage on each test run)

bartuka16:07:44

@lukaszkorecki thanks, I'm on it right now

potapenko18:07:06

Interop Bindings for all JDK classes (with docs): https://github.com/clojure-interop/java-jdk

4
hiredman18:07:30

is interop so bad that it needs wrapping?

lukasz18:07:00

How are reflection warnings handled? (I like the idea though!)

seancorfield18:07:16

@potapenko It looks like you'd get a lot of reflection warnings from using that library? There are no type hints on return types or on this in any of the argument lists.

potapenko21:07:00

1.0.1 - added types for argument list

seancorfield21:07:59

^. ? Not seen that before...

seancorfield21:07:55

Seems like that should be the class type that the namespace is a wrapper for?

seancorfield21:07:09

I know what a type hint is -- I've never seen ^. before. I don't think that is legal.

seancorfield21:07:32

All of the this parameters seem to have ^. in front of them instead of ^some.class.Type

potapenko21:07:44

send link please? to code

seancorfield21:07:32

Those were the first two things I checked because I work with JDBC so much (as the maintainer of clojure.java.jdbc in Contrib and next.jdbc).

👍 4
potapenko21:07:23

that bug 🙂 thanx

seancorfield22:07:03

Nice. Any thoughts on type hinting return types? Is that harder?

potapenko22:07:22

return type hint? What is the syntax?

seancorfield22:07:06

https://clojure.org/reference/java_interop#typehints 🙂 At the end of that section, just before the Aliases section.

potapenko22:07:26

о! I missed it.

potapenko22:07:06

added returns types 🙂

seancorfield18:07:30

Hah, yeah, what @lukaszkorecki said 🙂

lukasz18:07:13

java -cp your.app.jar 2>&1 | grep -v 'Reflection' #fixed

hiredman18:07:32

I mean, it seems like maybe you put a lot of time in, and it would be a useful way to see an and check out the apis, but outside of being a learning experience, wrappers without additional functionality are not something I would use

potapenko08:07:57

1. Autocomplete (instance members first) 2. Docs lookup 3. code native look I did a lot interop, and in almost all projects the same interop code. I thought that I needed to solve this problem radically. Make a binding generator. I plan to create some more libraries of bindings. If you have any ideas - welcome.

noisesmith18:07:17

@lukaszkorecki sure - if you're OK with an app that's 10-100x slower

noisesmith18:07:52

(in all fairness that's a hypothetical and it really depends on how you are using the reflective functions and where)

lukasz18:07:59

Yeah, ignoring reflection warnings is def not a good idea (although I found a couple of places where it's hard to type hint the code because of var-args in Java)

potapenko18:07:05

thanx @seancorfield i’ll add type hints soon.

noisesmith18:07:17

@lukaszkorecki fakeup of my workflow for that:

user=> (type (into-array ["foo"]))
[Ljava.lang.String;
user=> (defn foo [^ "[Ljava.lang.String;" args] ...)

lukasz18:07:59

Oh, I might try that - thanks!

noisesmith18:07:41

some people even make an empty <some type> array at compile time then get the string of the class automatically but to me just pasting the right string in usually makes more sense

antonmos19:07:50

Does anyone know what the best way to configure timbre for running tests with lein test is? Where do I call timbre/merge-config?

seancorfield19:07:14

@antonmos It probably depends on exactly what you're trying to do but I would probably make it a :once test fixture and include it in the namespaces where logging configuration matters?

antonmos20:07:05

i am trying configure timbre to not spam output with logs from java libs 🙂

hiredman20:07:07

my favorite thing to do with logging in tests is to have a logging configuration that is only active for tests that directs logs to a file in ./logs

12
clj 4
antonmos16:07:37

yup, i agree. i am looking for a way to do it with timbre logging lib

hiredman20:07:26

it is great, you get nice clean output, and the logs are there if you need to look at them

paulocuneo23:07:15

Hi, can record constructors be annotated?

noisesmith23:07:47

I don't think so - because they are auto-generated

noisesmith23:07:28

honestly for something that requires an annotated constructor I'd be tempted to make a java shim - it can use interop to call clojure for the bodies of all its methods, but I think that's simpler in the end than sculpting something that works using gen-class - maybe someone whose better with gen-class has a better suggestion though

noisesmith23:07:05

calling clojure functions from java code (as long as you are the one writing the java and the clojure) is simple

paulocuneo23:07:12

oh ok, thanks! will use .java then

paulocuneo23:07:04

it would have been nice though

noisesmith23:07:51

to me it's one of two corners of dev (the other being simple, performant numerics) that are sadly just easier to do in a java file most of the time

noisesmith23:07:11

luckily mixed java/clojure in arbitrary combinations is easy to do

noisesmith23:07:46

others opinions may vary (I'm surprised nobody has argued for gen-class yet actually)

noisesmith23:07:59

@lukaszkorecki yes - this is why I mention it, also it's clumsy to use and more complex than the equivalent java imho

noisesmith23:07:49

or maybe it's just that I find a java file much more readable than the weird hash-map dsl of gen-class clauses

lukasz23:07:08

yeah, I wouldn't use gen-class for anything more complicated than a class with a single method