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?
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?
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.
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.
(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.
@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.
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.
My first question: is this code in a public repository (e.g., GitHub) where we can take a look and provide suggestions?
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.
Connection to localhost:5432 refused
It expects you to have a PostgreSQL database running somewhere for it to connect to.
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
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.
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.
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.
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.
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.
Hello all, Is there any open source project where a beginner can contribute and learn Clojure at the same time?
Check out #contributions-welcome
would you like learn deep learning and clojure at the same time? Here is the project: https://github.com/kimim/clj-djl
Thank you very much
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]"]}}}
I just have to run clj -R:dev
then do :FireplaceConnect 5555
right?
But it doesn't work that way. For the record, I tried it with lein repl
and it worked flawlessly.
What is -R
? Also your cider/cider-nrepl
seems old. I think the current version is 0.25.8
THere's also the #contributions-welcome channel where you can find a list of some requests for help π
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)
Someone recently complained about the same error regarding -X
and I believe the problem was that their clj
version was too old
@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
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
In a nutshell:
REPL -> :A
main -> :M
execute function -> :X
If I'm not mistaken,
edit: :A
is in legacy mode and will eventually be replaced by the other two-A
will not be replaced, it will just stop using main-opts at some point.
Mmm, I'm on 1.10.1
But let me try updating nonetheless
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
ahh, 1.10.1.507
yup, that's a year and a day old π
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)
Huh, figures. All right, I'll finish updating then I'll try again. Thanks.
Don't forget to try -M
as well, after the update
@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
Oh, that's right, thanks!
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))
Are you trying at add a newline to each folder path in folders?
π First I like to sort the folders and then add a newline.
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.
:thinking_face: Ok I'll give it a try. Thank you for the hint.
A lot easier to read on mobile too lol
How did you create folders? I expected a list of strings not symbols.
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.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.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
That is the cache of constants used by the compiled function
hmm, as I suspected this is not a solution
The destructuring information is not part of the compiled function, it is macroexpanded away
macroexpanded away means "lost"
?
Yes, it is a one way transformation
Destructuring function arguments becomes a let binding inside the function body that pulls apart and names the relevant parts
The jvm supports annotating bytecode with some debugging information (file, line, and local variable names)
And the clojure compiler does fill in some of that
But the java reflection api doesn't give you access to it, so getting at the info is tedious
ok, I understood
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
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
(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?