beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
Mr. Savy 2021-01-31T00:33:23.255Z

hello! most of the work i've done with clojure has been with cljs. I now have a cljs project with a clj backend and it occured to me, after trying to debug my backend, that I don't really understand anything related to building a clojure application (using the clojure command). Does anyone know of any resources they could point me towards?

2021-01-31T01:46:31.255100Z

When you say "building a Clojure application", there are a few different things. you might mean. At least two I am aware of are (a) using the clojure command to run a Clojure program, given its source code, or (b) creating a JAR file with the Clojure source code, plus any libraries it depends upon, so that it is possible to run the application using only a java -jar foo.jar command, without needing to get any other code from anywhere else. Do you mean one of those?

2021-01-31T01:47:30.255300Z

Option (a) typically requires having the Clojure CLI tools installed on the machine, and downloading dependencies over the Internet from web site, if they are not already cached locally on th machine running the clojure command.

2021-01-31T01:48:12.255500Z

Option (b) requires a step or three to create the JAR file, but once that is done, you only need a Java runtime installed on the machine where the application is run, not the Clojure CLI tools, and no downloading of source or other code required.

Mr. Savy 2021-01-31T01:53:37.255700Z

(b) is the main case. I need to understand the general semantics for creating jars, running them, and debugging them. Right now I have a clojure backend that throws various errors and I don't have the know-how to understand what exactly the errors mean and how to fix them.

seancorfield 2021-01-31T04:19:15.256Z

@ajsnow2012 The best approach with backend code -- Clojure -- is to work with a running REPL and evaluate and test small pieces of code as you build it up.

seancorfield 2021-01-31T04:21:24.256200Z

What you have in a JAR file now is something you could run directly in a REPL and debug it that way but perhaps if you tell us a bit more about the errors you're seeing, we can given you some guidance on how to track down the causes and debug the code.

seancorfield 2021-01-31T04:21:58.256400Z

My first question: is this code in a public repository (e.g., GitHub) where we can take a look and provide suggestions?

Mr. Savy 2021-01-31T04:35:16.256600Z

the repo i'm trying to learn from is https://github.com/Folcon/fulcro-template after we build the application and release the frontend app my understanding is you can run the command java -cp fulcro.jar clojure.main -m app.server-main to run the jar for the backend. however, I've run into different errors when trying to do this. right now my problem is a refusal to connect, and it's pointing me to a few different areas when I look at the attached log.

seancorfield 2021-01-31T04:40:30.257Z

Connection to localhost:5432 refused It expects you to have a PostgreSQL database running somewhere for it to connect to.

seancorfield 2021-01-31T04:45:10.257200Z

The template mentions a "mock database" but I don't see any instructions about setting that up, nor do I see any reference to PostgreSQL -- beyond references to database-related libraries in deps.edn: https://github.com/Folcon/fulcro-template/blob/master/deps.edn#L25-L29

seancorfield 2021-01-31T04:48:28.257700Z

Ah, here's the config for your database connectivity: https://github.com/Folcon/fulcro-template/blob/master/src/main/config/dev.edn -- so, yes, it's expecting you to be running PostgreSQL somewhere and to update this EDN file to reflect how to connect to that database.

Mr. Savy 2021-01-31T05:07:35.258Z

oh, thank you! I wanted to see if I could set up a working page with no data but if I need to set one up I can learn how to I suppose. I was hoping I wouldn't need to set one up, but I guess you can't have a working backend without one.

seancorfield 2021-01-31T05:17:57.258500Z

This is why I tend to recommend learning Clojure without these giant, complex templates. They tend to have so many moving parts that it's hard to learn the language without learning a lot of "irrelevant" stuff about the template instead and all the libraries it builds on top of.

πŸ‘ 1
βž• 1
seancorfield 2021-01-31T05:18:49.258700Z

I see people trying to learn Clojure via the Luminus template and that's just a disaster most times. These templates make so many assumptions about what their users already know.

Mr. Savy 2021-01-31T05:32:38.258900Z

I learned mostly vanilla cljs on my own and that was a fun experience, but a lot of the details were abstracted away by stuff like leiningen which made it easier not to get stonewalled. fulcro has been an interesting yet harrowing experience all its own, but now, in particular, I'm having to learn a lot more about build tools and sever management. on one hand i've learned a lot but on the other it feels like it takes so much time to move forward just an inch. not that it's the fault of anything here. it just takes a lot of patience from myself and the others here who offer help. thank you for taking the time! I hope I can get this figured out.

Ricardo Cabral 2021-01-31T09:01:19.259700Z

Hello all, Is there any open source project where a beginner can contribute and learn Clojure at the same time?

πŸ‘ 1
pavlosmelissinos 2021-01-31T09:07:13.260600Z

Check out #contributions-welcome

πŸ‘ 1
2021-01-31T09:07:30.260800Z

would you like learn deep learning and clojure at the same time? Here is the project: https://github.com/kimim/clj-djl

πŸ‘ 1
Ricardo Cabral 2021-01-31T09:08:28.261300Z

Thank you very much

2021-01-31T09:25:07.262300Z

Hello, I'm having trouble figuring out how to run an nREPL server using deps.edn:

{:paths ["src"]
 :deps  {org.clojure/clojure {:mvn/version "1.10.1"}}

 :aliases
 {:dev {:extra-deps {cider/cider-nrepl {:mvn/version "0.18.0"}}
        :main-opts ["-m"           "nrepl.cmdline"
                    "-b"           "127.0.0.1"
                    "-p"           "5555"
                    "--middleware" "[cider.nrepl/cider-middleware]"]}}}

2021-01-31T09:25:44.263100Z

I just have to run clj -R:dev then do :FireplaceConnect 5555 right?

2021-01-31T09:26:24.263800Z

But it doesn't work that way. For the record, I tried it with lein repl and it worked flawlessly.

valtteri 2021-01-31T09:32:49.264800Z

What is -R ? Also your cider/cider-nrepl seems old. I think the current version is 0.25.8

dharrigan 2021-01-31T09:39:30.265100Z

THere's also the #contributions-welcome channel where you can find a list of some requests for help πŸ™‚

πŸ‘ 1
2021-01-31T10:09:15.265300Z

run? -A didn't work and -X gave me an error I couldn't quite google:

Execution error (FileNotFoundException) at java.io.FileInputStream/open0 (FileInputStream.java:-2). 
-X:dev (No such file or directory)

lassemaatta 2021-01-31T10:53:44.265700Z

Someone recently complained about the same error regarding -X and I believe the problem was that their clj version was too old

1
pavlosmelissinos 2021-01-31T12:35:42.266Z

@signup867 try clj -M:dev As you can see here: https://clojure.org/reference/deps_and_cli#_arg_map_keys :main-opts is ignored by the other flags

pavlosmelissinos 2021-01-31T12:38:47.266200Z

If that doesn't work either, check what you get from clj -Sdescribe and if that's https://github.com/clojure/brew-install/blob/1.10.1/CHANGELOG.md, consider updating your version of clojure

1
pavlosmelissinos 2021-01-31T12:47:26.266600Z

In a nutshell: REPL -> :A main -> :M execute function -> :X If I'm not mistaken, :A is in legacy mode and will eventually be replaced by the other two edit: -A will not be replaced, it will just stop using main-opts at some point.

2021-01-31T12:48:28.266800Z

Mmm, I'm on 1.10.1

2021-01-31T12:48:49.267Z

But let me try updating nonetheless

pavlosmelissinos 2021-01-31T12:50:44.267200Z

1.10.1 doesn't say much, did you check the changelog? There are 1.10.1 builds going 1.5 years back! You need the minor version too, e.g. 1.10.1.763

2021-01-31T12:51:07.267400Z

ahh, 1.10.1.507

pavlosmelissinos 2021-01-31T12:51:38.267600Z

yup, that's a year and a day old πŸ˜›

pavlosmelissinos 2021-01-31T12:51:53.267800Z

and doesn't support -X, according to the changelog (you don't need it here, I'm just mentioning it because you've tried it)

2021-01-31T12:52:49.268Z

Huh, figures. All right, I'll finish updating then I'll try again. Thanks.

πŸ‘Œ 1
pavlosmelissinos 2021-01-31T12:53:50.268500Z

Don't forget to try -M as well, after the update

alexmiller 2021-01-31T15:04:58.270600Z

@pavlos FYI, -A is not going away (you need it to supply aliases when starting a repl!) but it will stop using :main-opts at some point

πŸ˜… 1
pavlosmelissinos 2021-01-31T15:08:03.270900Z

Oh, that's right, thanks!

Sophie 2021-01-31T16:40:36.281500Z

Hey I'm trying to sort something like this and its really a mess. Finally I found a "solution" but there is a new problem... There must be a better way out there. This is the input:

(println folders) 
=>(/folder1/folderb/folderb1 /folder3/folderb/folderb1 /folder2/folderb/folderb1 )
(println(str (join #"\n" (sort(split (apply str(join "\n" folders)) #"\n"))))) 
=> (/folder1/folderb/folderb1\\n /folder2/folderb/folderb1\\n /folder3/folderb/folderb1)
The problem is the \\n it should be just \n so what's wrong and is the a more elegant solution? It doesn't feel right this way. This is not really the solution but it works πŸ˜‰
(join "\n"(sort del-file-names))

Bret Horne 2021-01-31T16:48:17.281700Z

Are you trying at add a newline to each folder path in folders?

Sophie 2021-01-31T16:55:00.282300Z

πŸ‘ First I like to sort the folders and then add a newline.

Bret Horne 2021-01-31T16:57:39.282500Z

There's a difference between #"\n" "\n" and \n . The first is a regex, the next is a string and the other is a liter character right. A literal newline looks like \newline.

Sophie 2021-01-31T17:03:53.282800Z

:thinking_face: Ok I'll give it a try. Thank you for the hint.

πŸ‘ 1
Bret Horne 2021-01-31T17:08:04.283100Z

A lot easier to read on mobile too lol

Bret Horne 2021-01-31T17:19:41.283700Z

How did you create folders? I expected a list of strings not symbols.

Bret Horne 2021-01-31T17:28:44.284Z

user> (def folders ["/folder1/folderb/folderb1" "/folder3/folderb/folderb1" "/folder2/folderb/folderb1"])

#'user/folders
user> folders
["/folder1/folderb/folderb1" "/folder3/folderb/folderb1" "/folder2/folderb/folderb1"]
user> (str/join "\n " (sort folders))
"/folder1/folderb/folderb1\n /folder2/folderb/folderb1\n /folder3/folderb/folderb1"
More aligned with how you’re doign it but note that join’s β€œ\n” is for seperating the values not necesarily appending to each item in folders.

Bret Horne 2021-01-31T17:33:31.284200Z

So appending a string to a string you’d use str.

user> (map #(str % "\n") (sort folders))
("/folder1/folderb/folderb1\n" "/folder2/folderb/folderb1\n" "/folder3/folderb/folderb1\n")
β€˜call str to each item in folders and add β€œ\n” and return the result as a vector’ could use map as well if a list is fine.

caumond 2021-01-31T23:31:12.290500Z

Hi guys, is there a way to introspect a function ? I have one function with named parameters

(def toto (fn [& {:keys [filename]}] (println "load filename:" filename)))
I'm looking for a way to do some introspection to discover the :filename inside the function parameter list. When I have a look to cider-inspect, I find a list of static fields I don't really understand. And not sure to know how to retrieve only the value :filename it seems to be a flat list of symbols:
Class: user$toto
Value: "#function[user/toto]"
---
Fields:
  "__methodImplCache" = nil

Static fields:
  "const__0" = #'clojure.core/seq?
  "const__1" = #'clojure.core/seq
  "const__3" = :filename
  "const__4" = #'clojure.core/println

2021-01-31T23:33:26.291400Z

That is the cache of constants used by the compiled function

caumond 2021-01-31T23:33:54.292300Z

hmm, as I suspected this is not a solution

2021-01-31T23:34:46.293700Z

The destructuring information is not part of the compiled function, it is macroexpanded away

caumond 2021-01-31T23:35:19.294400Z

macroexpanded away means "lost"

caumond 2021-01-31T23:35:23.294700Z

?

2021-01-31T23:35:36.295200Z

Yes, it is a one way transformation

2021-01-31T23:36:55.297100Z

Destructuring function arguments becomes a let binding inside the function body that pulls apart and names the relevant parts

2021-01-31T23:38:29.299900Z

The jvm supports annotating bytecode with some debugging information (file, line, and local variable names)

2021-01-31T23:39:03.300800Z

And the clojure compiler does fill in some of that

2021-01-31T23:39:54.302700Z

But the java reflection api doesn't give you access to it, so getting at the info is tedious

caumond 2021-01-31T23:40:13.303100Z

ok, I understood

2021-01-31T23:43:21.308Z

If the function is a defn and you have the var, not just the function object, you can inspect the :arglists metadata on the var

2021-01-31T23:45:35.311300Z

That can be kind of brittle though since that information is part of what doc prints out at the repo, so people have a tendency to fiddle with it to make better documentation, in which case it doesn't actually match the real arglists of the fn

caumond 2021-01-31T23:50:09.313400Z

(meta (var toto))
where
(defn toto [& {:keys [filename]}] (str filename))
is ok. I may have an issue with my english maybe, but I don't understand your last sentence "in which case it..." . @hiredman Do you mean :arglists metadata are not reliable?