Fork me on GitHub
#beginners
<
2022-04-21
>
lassemaatta06:04:52

any ideas or tools I could use to search a project for instances of when where the body has more than one form? e.g. to find possible bugs like (when foo? 1 2 3).

lassemaatta06:04:00

ah, I should have guessed borkdude had a tool for this :)

Roee Mazor07:04:31

hey hey, if I have memory leaks, whats the “Valgrind” for Clojure in that case? (using k8 if that matters)

jumar07:04:23

There are multiple tools you can use, notably some java profilers like VisualVM, YourKit, etc. There's also async-profiler which has some support for tracking allocations. And of course you can still use valgrind, jemalloc, etc - especially if your app is leaking native memory But the very first thing would be to examine why you think you have a memory leak. I really recommend reading through https://stackoverflow.com/questions/53451103/java-using-much-more-memory-than-heap-size-or-size-correctly-docker-memory-limi/53624438#53624438

Roee Mazor08:04:06

Thanks a lot! Ill go do some reading 🙂

jumar08:04:09

So back to your question: why do you think you have a memory leak?

Roee Mazor08:04:29

When we run in docker everything seems fine, when we run in k8 it crashes after 1 minute after it reaches 30gb of memory or more. (I am helping a friend, so not really sure whats happening there, haven’t seen it happening myself)

jumar08:04:27

Hmm, that's strange. As long as the workload is the same... • I would start by examining what the application is doing (understanding the program and checking logs). • Then observe high-level memory usage via standard linux tools (e.g. top and free) • Then dive deeper using jvm specific tools like jcmd, jstat, etc.

Roee Mazor08:04:57

sounds like a plan, will update what we found, thx!

Leon Romo07:04:45

hey guys in an instance where one wanted to compare parallel elements in a vector, how would one go about it? For example [ 3 5 6] & [2 9 4]

Bart Kleijngeld08:04:25

I'm not sure I understand what you're looking for, but it seems this is only true if the vector elements are equal (position-wise). So couldn't you just say:

(= [3 5 6] [2 9 4])
It really depends on the exact desires you have

Leon Romo08:04:50

Sorry I meant individual elements in the vector...

Leon Romo08:04:25

but your explanations serves about right. Thanks 😁

1
Bart Kleijngeld08:04:32

Those are being compared.

(= [1 2 3] [1 2 3])  ;; true
(= [1 2 3] [1 2 4])  ;; false

Bart Kleijngeld08:04:47

You're welcome 🙂

Stel Abrego08:04:49

Hey hey, I'm trying to do Java interop and I just can't get this code to work. I'm trying to create a Class that implements this protocol: https://javadoc.jitpack.io/com/github/bailuk/java-gtk/main-fb80fb6f1c-1/javadoc/ch/bailu/gtk/gio/Application.OnActivate.html. I think there might be some weirdness because the interface name contains a period? Here's what I have:

(ns user
  (:import
   (ch.bailu.gtk.gio Application.OnActivate))

(def activate (proxy [Application.OnActivate]  []
                (onActivate [this]
                  (println "hi"))))
I've tried so many permutations of importing and classnames and all of them return an error like this:
Caused by: java.lang.ClassNotFoundException: ch.bailu.gtk.gio.Application.OnActivate
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:476)
	at clojure.lang.DynamicClassLoader.findClass(DynamicClassLoader.java:69)
I know the package and interface is available in my local maven cache because I have a working Java program that uses this library. I'm just trying to rewrite it in Clojure. How can I access that interface from Clojure land?

jumar09:04:50

That's a nested class. Did you try to import it with $ instead of . ? Something like this

(:import
   (ch.bailu.gtk.gio Application$OnActivate))

(def activate (proxy [Application$OnActivate]  []
                (onActivate [this]
                  (println "hi"))))
I also think you are missing a paren at the end of the ns declaration - there should be three parens, not just two

🙏 1
Serafeim Papastefanos08:04:37

hey friends, i've got this code:

(defn foo-middleware [handler]
  (fn [request]
    (log/info "foo-middleware")
    
    (assoc
     (handler (assoc request :foo-request-key "foo-request-key"))
     :foo-response-key "foo-response-key")))
Notice that I want to call the log first and then return the (assoc...). This works however I'd like to understand if that way of writign this is idiomatic or i should put these two expression inside some other expression

Serafeim Papastefanos08:04:28

Here's a simpler example of my question:

(defn add [a b]
  (log/info "Adding a and b")
  (+ a b))
Is this idiomatic ?

Serafeim Papastefanos11:04:44

thank you i thought there was a way to run these sequentially

Baye12:04:41

Newbie question. Are the following equivalent: Reframe Nextjs, reitit reacted router, Datomic ~ sql. And Ring? If so, what is the equivalent of the typical backend such as Express? And many examples I see online use sql not datomic or am I mixing things? Thanks

leifericf13:04:00

SQL is a query language for interacting with relational databases, such as MySQL, SQLite, and PostgreSQL. Datalog is similar to SQL in the sense that it’s a query language for interacting with deductive databases, such as Datomic. Clojure is a general-purpose programming language that can be used to interact with all of those database technologies through libraries. Depending on your needs, you might choose one or the other database technology. I don’t know about those other JavaScript things you mentioned to comment on their similarity to those Clojure things you mentioned.

👍 1
leifericf13:04:38

Also, if I may offer some general advice: In my experience, it’s more frustrating to look for “equivalent” libraries between the [some other language] and Clojure ecosystems than to focus on the general concept or problem and then look for a Clojure library that deals with that. For example, instead of thinking, “what is the equivalent of the typical backend such as Express,” consider thinking, “how would I do [some concept] in Clojure?” where candidates for [some concept] could be things like routing, HTTP helpers, or content negotiation. I understand that it’s easier to learn something new in the context of something familiar, and you should do that. But try to focus on the familiar concepts underlying the JavaScript libraries instead of their implementation details. Because the implementation details are more likely to differ significantly between different programming language ecosystems.

👍 1
practicalli-johnny13:04:04

Agreed, its much easier to ask how to do something that try match stacks. Ring turns http requests into Clojure hash-maps and is a defacto library used by most back-end routing libraries Ring provides an adaptor to embed a server-side application server (jetty, http-kit, tomcat, etc) that serves static and dynamically generated content (often from a database) Compojure or Reitit are common routing libraries (with reitit and a few other projects also supporting front-end routing as well as back-end routing) A database can be relational, like postgres, used via next.jdbc (sql statements) or honeysql (clojure data sturcture queries) Or a database can be "not sql", like datomic, XTDB, mongodb kafka, hadoop, etc

👍 1
Baye14:04:06

Thanks, makes sense

Baye17:04:19

Btw, I forgot to mention: one of the reason I was asking about Datomic vs SQL etc in relation to Clojure project I saw online was given the benefits touted for Datomic, wouldn't most projects use it?

leifericf08:04:01

Datomic is a great database to use with Clojure. However, it’s a commercial product, meaning https://www.datomic.com/pricing.html. That’s not necessarily “bad” because it provides Cognitect with the financial resources required to develop and support the product. But that also means that many developers, especially individuals and small teams, might opt for an open-source alternative, such as https://github.com/threatgrid/asami or https://xtdb.com. Whether Datomic is the “best” choice for your project depends on many factors, such as your budget, what kind of problem you’re trying to solve, technical constraints, etc. What are the characteristics of the problem you’re trying to solve? What are your constraints? In summary: You can use any database with Clojure. Datomic is one of many viable options, with particular pros and cons. You must evaluate which option is “best” within your context. Maybe it’s Datomic.

👍 1
Jeanette S.14:04:04

Hi, I found an interesting project developed with clojure (https://github.com/yetanalytics/project-persephone), but unfortunately I don't know clojure (only java and some python). Ideally I'd just like to call a few functions with some data. Was able to figure out how to call functions on the commandline with the format 'clj -X namespace/functionname', but my input did not seem to be in the correct format (e.g. 'clj -X namespace/functionname :param "a"' expected a string but gave error: "class clojure.lang.PersistentArrayMap cannot be cast to class java.lang.String"), and I don't know how I can store data returned from functions in this way to use the data as input to other functions. Is there a better approach? Any advice appreciated!

dorab16:04:37

I presume you're not on Windows. Not sure if this is your exact issue, but in order to pass a string at the command line you need to quote the double quotes from the shell as follows: clj -X namespace/fnname :param '"a"'

hiredman17:04:30

-X passes a map to the function it calls, that error indicates somewhere that something was expecting a string and was passed a map

didibus01:04:26

You can call Clojure from Java

didibus01:04:39

Create a Java project

didibus01:04:51

Add the clojure library as a dependency, add Clojure as a dependency as well

Jeanette S.06:04:31

Thanks for all your replies 🙂 I will try again later today

Daniel Pease16:04:06

hi all! would love suggestions for a collaborative clojure learning env - details in thread

Daniel Pease16:04:24

Basically, myself and some of my compatriots (10-15) of us want to get together and run through some intro-to-clojure interview style problems (think fizz-buzz etc). it would be great if we could all see and interact with the same repl in real time. anyone know of anything like that? i was looking at http://repl.it but tbqh (and maybe this is because i’m quite a noob myself) i couldn’t figure out how to get it to print ‘hello world’ 😅

respatialized16:04:48

maria.cloud may be what you're looking for!

respatialized16:04:57

Oh, but it doesn't have the collaborative REPL bit

Daniel Pease16:04:32

alas it does not - but this is super cool regardless, thanks for sharing!

respatialized16:04:29

Clojurescript can apparently be made to work on Glitch, which may handle the multiplayer aspect: https://glitch.com/edit/#!/clojurescript-on-glitch

Daniel Pease17:04:06

ooh these are both promising! i’ll look into these and will update the thread with findings

practicalli-johnny21:04:31

I've used VSCode, Calva and VSpaceCode (vim-style editing and control) to collaborate with others and it worked very well VSCode Live Share allows each person to follow their own cursor of a cursor of another person, although you can loose yourself if you forget you are following someone else. It is pretty well organised once you have spent a bit of time getting used to it. If the Calva key bindings are not to your taste, a preferred Clojure editor can be used to edit the files that VS Code is sharing and both editors should autoload changes in the files they have open. Its not as collaborative as using VScode directly. Alternatively you could use a shared server that has Clojure installed. Create a project and expose the REPL port (over SSH for security) and edit the flles via SSH (e.g. tramp in Emacs). This is a bit more involved and doesnt have the nice collaborative UI, but then there is no reliance on VSCode.

bringe23:04:10

There’s some guidance here on using Live Share with Calva. https://calva.io/live-share/

bringe23:04:43

Note that it must be enabled due to an issue affecting some users. > Due to https://github.com/MicrosoftDocs/live-share/issues/4551, for some users, this feature stops Calva from connecting the REPL. Therefore the support is disabled by default. The setting is calva.useLiveShare.

Jim Strieter16:04:44

I have a local jar file which I built with Idea: ~/Java2Import/artifacts/Java2Import/Java2Import.jar I want to import in Leiningen. How do I do that? I searched for a forum, but all the existing answers require Maven, which is not an option for what I'm doing.

delaguardo17:04:43

you can add :resource-paths with a vector of paths to local jars

Jim Strieter17:04:28

How do I import into a namespace?

delaguardo18:04:15

Same as usual. Require and import does not depend on how you include sources

Jim Strieter18:04:03

When I type at the repl: (import [Java... and then press Tab, the REPL does not complete the classname (Java2Import). What am I doing wrong?

delaguardo18:04:43

Adding local jars through resources isn't a normal way for clojure applications. I wouldn't expect any editor to know what to suggest

Jim Strieter18:04:38

The examples that I found for Java interop all assume that you're importing something from the web. What syntax should you use at REPL for local jar?

Jim Strieter20:04:21

For example:

import-local-java-4.core=> (import (Java2Import Java2Import))
Execution error (ClassNotFoundException) at java.net.URLClassLoader/findClass (URLClassLoader.java:476).

Jim Strieter20:04:14

import-local-java-4.core=> (import (Java2Import.Java2Import))
Syntax error macroexpanding clojure.core/import at (/tmp/form-init9909516591129619328.clj:1:1).
Java2Import.Java2Import - failed: #{(quote quote)} at: [:class :quoted-spec :quote] spec: :clojure.core.specs.alpha/quotable-import-list
() - failed: Insufficient input at: [:package-list :spec :classes] spec: :clojure.core.specs.alpha/package-list
Java2Import.Java2Import - failed: #{(quote quote)} at: [:package-list :quoted-spec :quote] spec: :clojure.core.specs.alpha/quotable-import-list
(Java2Import.Java2Import) - failed: simple-symbol? at: [:class :spec] spec: :clojure.core.specs.alpha/quotable-import-list

delaguardo07:04:07

what is the classname you want to import?

dgb2318:04:16

is there a spec for deps.edn files?

dgb2318:04:12

if not, might be useful for editors and tooling around project setup

seancorfield18:04:59

I think clj-kondo can lint it but I don't know whether it catches everything.

👍 1
dgb2318:04:52

Are things like ::aliases deliberately loose, or is it more of a work in progress kind of thing? Is this for public consumption? What about the many string? specs (mvn versions, urls, etc.)

dgb2318:04:09

In any case: thank you very much 🙂

Alex Miller (Clojure team)19:04:01

:aliases can hold any data

Alex Miller (Clojure team)19:04:45

I don't find it to be a wise use of time to get any more detailed than string?

Alex Miller (Clojure team)19:04:59

esp for data formats I don't control :)

dgb2319:04:51

Thank you that makes sense!

seancorfield19:04:49

Right now, the only things built-in that use aliases-as-data are the various :paths options (+ replace, extra) but 3rd party tooling can use aliases for anything it wants. We use that capability at work to define uberjar options that we extra from the project's deps.edn file (via t.d.a's find and merge) to drive stuff in our build.clj file.

👍 1
seancorfield19:04:13

deps-deploy also supports aliases-as-data in several places (as did depstar before I sunsetted it).

👍 1
Alex Miller (Clojure team)19:04:08

all aliases are data, some are just used by tools.deps

dgb2319:04:46

Right I‘m such a fool, always try to read specs top down (bottom up in the source) but that’s not how it works. Extra paths etc are still specced „inside“. :)