Fork me on GitHub
#beginners
<
2022-04-25
>
rayat00:04:24

Any docstring "standards" or conventions out there that tooling can take advantage of, or even is just a convention at all? Eg JSDoc in javascript world. It's structured enough and ubiquitous enough that IDEs like vsc can lint or guide completions and whatnot on the basis of these docstrings and even use them as soft type hints.

Cora (she/her)00:04:17

cljdoc supports markdown in docstrings

Cora (she/her)00:04:45

I would love if we had a standard for type signatures for args and return types and multiple arities

😿 1
1
dgb2306:04:07

However, there are parameter naming conventions like m , s , coll ,`xform`etc.

rayat06:04:55

I don't even know those conventions lol

dgb2306:04:50

They might not be as strong as I thought? But they are used throughout clojure core and other libs. When you see m you know it’s probably a map and so on.

rayat16:04:47

Huh! That's awesome, thanks for sharing that, didn't know it existed, though not surprised it's from bbhatsov either!

dazld15:05:06

(sorry for necromancy) I truly miss jsdoc style annotations in comments for functions. I guess clojure has better theoretical possibilities with macros - but in practice, it feels too intrusive, too much opinion - the base language is already great. comments and the base language are just in that sweet spot of being familiar enough to adopt and powerful enough to provide value.

1
Yogesvara Das08:04:50

Is it possible with reframe to have different parts of a panel subscribed to different things? I'm trying to not make the main page refresh when my navbar UI is interacted with.

lsenjov08:04:13

Is your navbar in its own component? Is your main page subs dependent on things getting updated from navbar events?

lsenjov08:04:36

If those are both true, then why would changing the navbar make the main page refresh?

lsenjov08:04:48

Remember that a reagent component only updates if the value of one of its "signalling" components changes (basically the things you deref)

lsenjov08:04:17

So if your main page refreshes, it's likely the value of one of the subs you subscribe to is changing value

Yogesvara Das08:04:06

Huh ok. I'll try have a look through my events and subs again to see if I missed something.

lsenjov08:04:15

Possibly also set up re-frisk to help you diagnose which subs are updating

👍 1
Peng Xiao08:04:19

I saw this snippet in using nbb. What is the $ sign in the require here? Is there any document describing it? Thanks!

aratare08:04:04

iirc it’s the default export

❤️ 1
Peng Xiao08:04:22

Ty @U04V15CAJ ! I will take a look 😄

leifericf11:04:31

This is probably a different scenario, but I recall being confused when I needed to use $ to access a Java class method. Specifically, this one (from my deps.edn): com.google.apis/google-api-services-mybusinessaccountmanagement {:mvn/version "v1-rev20220215-1.32.1"}. In my namespace, I had to import it like so: com.google.api.services.mybusinessaccountmanagement.v1 MyBusinessAccountManagement$Builder. In https://googleapis.dev/java/google-api-services-mybusinessaccountmanagement/latest/com/google/api/services/mybusinessaccountmanagement/v1/MyBusinessAccountManagement.Builder.html, there is a . in place of the $. I still don’t understand why $ is needed here in Clojure, and it took an embarrassingly long time to figure out why I couldn’t use MyBusinessAccountManagement.Builder (notice the .) when importing it.

borkdude11:04:01

In Clojure JVM, the dollar sign is for accessing inner classes.

👍 1
leifericf11:04:42

Thanks, @U04V15CAJ! It looks like that’s what I learned the hard way 😅

leifericf11:04:31

This is probably a different scenario, but I recall being confused when I needed to use $ to access a Java class method. Specifically, this one (from my deps.edn): com.google.apis/google-api-services-mybusinessaccountmanagement {:mvn/version "v1-rev20220215-1.32.1"}. In my namespace, I had to import it like so: com.google.api.services.mybusinessaccountmanagement.v1 MyBusinessAccountManagement$Builder. In https://googleapis.dev/java/google-api-services-mybusinessaccountmanagement/latest/com/google/api/services/mybusinessaccountmanagement/v1/MyBusinessAccountManagement.Builder.html, there is a . in place of the $. I still don’t understand why $ is needed here in Clojure, and it took an embarrassingly long time to figure out why I couldn’t use MyBusinessAccountManagement.Builder (notice the .) when importing it.

Ho0man12:04:16

Hi everyone, is it possible to define metadata on the record when using defrecord macro to define it ?

Alex Miller (Clojure team)13:04:05

record instances take metadata. I'm confused by what you mean on defrecord though

Ho0man13:04:34

Thanks @U064X3EF3 We use a variant of stuartsierra's component library to build our systems and we wanted to know whether there is a way to set a component's dependency as part of its defrecord by setting the metadata on the record itself came to mind so that later on when instantiation instances we can check the dependencies.

Alex Miller (Clojure team)13:04:37

you can make a record constructor function that sets metadata on the record instance

Jim Strieter15:04:24

I am trying to add java.sql.Connection to project.clj in :dependencies. My question is, "Where do I find the latest version for java.sql.Connection?" (I'm not very experienced in Java.) For instance, when I go to https://docs.oracle.com/javase/7/docs/api/java/sql/Connection.html, it's not obvious to me what the latest version number is

delaguardo15:04:49

java.sql.Connection provided to you by used JDK

delaguardo15:04:03

you don't need to add it to dependencies 🙂 it comes for free

Serafeim Papastefanos15:04:47

It is possible to have dependencies only for development in a deps.edn project?

Darin Douglass15:04:58

you can use the :extra-deps key to add deps to a given alias, then use that alias when spinning up your repl/tests/whatever

Serafeim Papastefanos15:04:26

Excellent thank you very much!

Jim Strieter15:04:50

I imported some java files I wrote a couple years ago into clj. One class, ConnectToPostgres used to work perfectly in an all java project in Idea. (Now I'm not using Idea anymore.) When I try to do this at the REPL:

(def uut1 (new ConnectToPostgres))
I get this:
Connecting to database...
java.sql.SQLException: No suitable driver found for jdbc:
	at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:702)
	at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:228)
	at JBarSource.ConnectToPostgres.<init>(ConnectToPostgres.java:20)
	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)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
	at clojure.lang.Compiler$NewExpr.eval(Compiler.java:2615)
	at clojure.lang.Compiler$DefExpr.eval(Compiler.java:457)
	at clojure.lang.Compiler.eval(Compiler.java:7181)
	at clojure.lang.Compiler.eval(Compiler.java:7131)
	at clojure.core$eval.invokeStatic(core.clj:3214)
	at clojure.core$eval.invoke(core.clj:3210)
	at clojure.main$repl$read_eval_print__9068$fn__9071.invoke(main.clj:414)
	at clojure.main$repl$read_eval_print__9068.invoke(main.clj:414)
	at clojure.main$repl$fn__9077.invoke(main.clj:435)
	at clojure.main$repl.invokeStatic(main.clj:435)
	at clojure.main$repl.doInvoke(main.clj:345)
	at clojure.lang.RestFn.invoke(RestFn.java:1523)
	at nrepl.middleware.interruptible_eval$evaluate.invokeStatic(interruptible_eval.clj:79)
	at nrepl.middleware.interruptible_eval$evaluate.invoke(interruptible_eval.clj:55)
	at nrepl.middleware.interruptible_eval$interruptible_eval$fn__939$fn__943.invoke(interruptible_eval.clj:142)
	at clojure.lang.AFn.run(AFn.java:22)
	at nrepl.middleware.session$session_exec$main_loop__1040$fn__1044.invoke(session.clj:171)
	at nrepl.middleware.session$session_exec$main_loop__1040.invoke(session.clj:170)
	at clojure.lang.AFn.run(AFn.java:22)
	at java.base/java.lang.Thread.run(Thread.java:829)
#'clojure-trade-bot-2.core/uut1
What am I doing wrong?

pavlosmelissinos15:04:44

1. does your project have a deps.edn/project.clj? What does it look like? 2. where is the java code located? have you built it into a jar? Is the jar deployed somewhere? 3. please use threads, it's hard to follow the conversation otherwise update: https://clojurians.slack.com/archives/C053AK3F9/p1650903059274279?thread_ts=1650901344.771399&amp;cid=C053AK3F9

Serafeim Papastefanos15:04:53

This seems to be missing a postgresql driver

🧵 1
Jim Strieter15:04:20

I already installed the postgresql driver at ~/.m2/repository/postgresql/postgresql/42.3.4/ Did maven deploy etc. Do i need to install an additional driver?

Serafeim Papastefanos15:04:24

Don't you need to include that in a pom.xml if it's a Java project?

Jim Strieter15:04:32

Oh I think you're asking if ultimately this project is a Java project. No. It's a Clojure project with imported Java.

Darin Douglass15:04:36

do you have it included in your deps.edn/project.clj file? having it on your filesystem isn’t enough for the JVM to know you need access to that dependency

Jim Strieter16:04:46

Yes. I added :java-source-paths ["src/MyJavaFiles/"] to project.clj

Darin Douglass16:04:59

you’ll also need to add the postgres driver to your :dependencies key

(defproject MyJavaFiles
  :dependencies
  [;; among others
   [org.postgresql/postgresql "42.3.1"]])

Jim Strieter16:04:33

OMG that worked!

Jim Strieter16:04:54

Thank you so much @U02EA2T7FEH 🙂

Eugen17:04:02

hi, is there a way to apply multiple updates in a cond-> branch ? Or another question: why does this work:

(cond-> 1 
  true inc)
and this does not
(cond-> 1
    true (fn [x] (* 3 (inc x))))
Context: trying to apply multiple update-in's to a map received by cond-> Evaluating inc and a fn in the repls yields:
#function[clojure.core/inc]
 
#function[my.ns/eval33358/fn--33359] 

Alex Miller (Clojure team)17:04:43

in short, because it's a macro

🧵 1
Eugen17:04:52

cond-> you mean?

Eugen17:04:09

because I checked inc and seems like a fn:

(defn inc
  "Returns a number one greater than num. Does not auto-promote
  longs, will throw on overflow. See also: inc'"
  {:inline (fn [x] `(. clojure.lang.Numbers (~(if *unchecked-math* 'unchecked_inc 'inc) ~x)))
   :added "1.2"}
  [x] (. clojure.lang.Numbers (inc x)))

Eugen17:04:43

I'm new at this - is there a way to have my cake?

Alex Miller (Clojure team)17:04:30

one option is to just make a named function and use that, or you can do something like this:

(cond-> 1
  true (#(* 3 (inc %))))

Alex Miller (Clojure team)17:04:51

but I would never inflict that on my future self as a code reader

Darin Douglass17:04:39

you could also

(cond-> 1
  true (->> (* 3 (inc)))
but mixing threading macros can be confusing

Alex Miller (Clojure team)17:04:04

but I'm not sure how this matches with your original stated problem - multiple update-in's should be fine?

Eugen17:04:19

I have to do multiple update-in's for the same condition:

(cond-> {:count count
             :articles articles
             :related-terms related-terms
             :cuis cuis
             :pmids pmids
             :st-counts st-counts
             :st-counts-elem st-counts-elem
             :rel-counts rel-counts}
      name-is-not-stop-word? (fn [coll]
                               (-> coll
                                   (update-in [:cuis [name-rel]] add-value-to-set cui)
                                   (update-in [:pmids [name-rel]] add-value-to-set pmid)
                                   (update-in [:count] inc))))

Eugen17:04:48

I have several conditions

Alex Miller (Clojure team)17:04:29

you could repeat the name-is-not-stop-word? condition and just do one-per

Eugen17:04:31

trying to get a single return instead of having code with several nested when + if's and multiple return expressions

Alex Miller (Clojure team)17:04:43

or let the anonymous function around the cond-> to give it a name

Eugen17:04:22

repeating the condition should be good enough imo

Alex Miller (Clojure team)17:04:31

or just don't use cond-> :)

Eugen17:04:42

did not think it would work and did not try

Alex Miller (Clojure team)17:04:15

(let [m ...] (if name-is-not-stop-word? (-> m ...) m))

Eugen17:04:46

this seems also a good option

Eugen17:04:58

thanks, I'll try these

Alex Miller (Clojure team)17:04:01

often helpful to macroexpand and see the expansion:

user=> (pprint (macroexpand-1 '(cond-> 1 true (fn [x] (* 3 (inc x))))))
(clojure.core/let
 [G__138 1]
 (if true (clojure.core/-> G__138 (fn [x] (* 3 (inc x)))) G__138))

user=> (pprint (clojure.walk/macroexpand-all '(cond-> 1 true (fn [x] (* 3 (inc x))))))
(let* [G__145 1] 
  (if true 
    (fn* G__145 ([x] (* 3 (inc x)))) G__145))

Alex Miller (Clojure team)17:04:09

note where the G__145 gets threaded - just dropped in as effectively the name of the anonymous function

Ted Ciafardini18:04:48

Is there an existing ‘source of truth’ for idiomatic solutions to 4clojure problems?

practicalli-johnny19:04:25

I would have found an idiomatic set of answers less useful than exploring different approaches and learning from those experiences I wouldn't consider my solutions a source of truth, but a journey of learning the core functions of Clojure https://youtube.com/playlist?list=PLpr9V-R8ZxiDB_KGrbliCsCUrmcBvdW16

💚 1
💯 1
Bobbi Towers20:04:06

There is a repo that aggregated the answers from the top 1000 users into a test corpus: https://github.com/mfikes/coal-mine

Drew Verlee21:04:47

Searching among the most terse answers is usually informative. You should see patterns emerge and it's worth looking at outliers to see if they are elegant or other...

Edward Ciafardini21:04:43

Thanks everybody