beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
caumond 2021-02-01T00:07:46.314500Z

For anybody who would be interested in the answer:

(defmacro named-parameters[f]
  `(map keyword ((comp :keys second first :arglists meta) (var ~f))))
(defn foo [& {:keys [filename yop]}] (str filename yop))

(named-parameters foo)

2021-02-01T00:09:06.315100Z

It is reliable enough if you are defining the function yourself, it can be unreliable for things from libraries

caumond 2021-02-01T00:12:44.315800Z

ah ok, I control the functions, no issues.

2021-02-01T03:17:32.316Z

i've tried to create projects, run the core.clj, but still the repl doesn't show up.

2021-02-01T04:54:12.316400Z

okay, found the solutions https://stackoverflow.com/questions/65566706/error-in-process-sentinel-could-not-start-nrepl-server-java-lang-numberformate 1. start git cmd 2. type >> lein repl >> it'll start repl in git cmd 3. goto doom emacs type [SPC m c] >> cider-connect-clj 4. choose local host 5. type port local host as shown in step 2

2021-02-01T05:30:53.319Z

Hi Guys, i'm using doom emacs now, and I don't know the shortcut for : 1. how to make my cider repl move to right panel? 2. [C c M p] >> is this the correct shortcut to send code from buffer to REPL? much appreciated for the help πŸ˜„

2021-02-01T13:41:28.331800Z

gotcha, 1. [SPC w v] to add window vertically 2. [SPC b B] to select the cider REPL poof we got buffer & REPL side by side vertically

1πŸŽ‰
pavlosmelissinos 2021-02-01T14:04:58.337300Z

FYI most of the time you don't even need the REPL buffer in the foreground

pavlosmelissinos 2021-02-01T06:41:05.321600Z

#emacs might be a better place to ask these questions Not sure about doom emacs but with vanilla emacs: 1. you can change the orientation with C-\ . 2. In general you usually don't send the code to the repl, but you evaluate it in place instead and the shortcut for that is C-c C-c or C-c C-e, depending on where the cursor is. From the https://docs.cider.mx/cider/usage/cider_mode.html: > Typically you'd begin your interaction with any source buffer by evaluating it with C-c C-k. Afterwards you'd normally evaluate just individual forms with C-c C-e (evaluate preceding form) or C-c C-c (evaluate current top-level form).

2021-02-01T06:45:28.321800Z

ah okay, will ask there

Henry 2021-02-01T07:31:44.328600Z

The deployment story of Clojure(Script) is very different than in JavaScript. On top of this, there are so many options that make beginners wonder which strategy to adopt. Experienced Clojurians, would you mind sparing a minute and share what you think are the state-of-the-art (or your favourite) deployment strategies? Any useful learning resources are also welcomed. Thanks a lot for sharing.

solf 2021-02-01T08:21:36.329200Z

For clojurescript, shadow-cljs is usually the recommended way. It makes integration with the npm ecosystem (almost) transparent. - https://github.com/thheller/shadow-cljs - https://shadow-cljs.github.io/docs/UsersGuide.html - #shadow-cljs

Henry 2021-02-01T14:24:08.338Z

@dromar56 Thanks for sharing. Shadow-cljs is indeed a fantastic tool for CLJS development and deployment. Do you use shadow-cljs with any other build tool for compiling CLJ, like into a uberjar, etc.?

solf 2021-02-01T14:39:17.338200Z

shadow-cljs is cljs-only. For clojure the two options are either - lein (battery included, but falling more and more out of favor) - or deps.edn, the offficial tool (https://clojure.org/guides/deps_and_cli) I prefer deps.edn, but it's pretty barebone. Building a jar with lein is simple:

lein uberjar
With deps.edn, you need to use something like depstar (https://github.com/seancorfield/depstar) Also interesting read if you want to use deps.edn: https://github.com/seancorfield/dot-clojure

Henry 2021-02-01T14:42:48.339200Z

Thanks a lot for helping. If you won't mind sharing, after you've got the frontend codes from shadow-cljs and the uberjar, how do you deploy to the web?

solf 2021-02-01T14:59:58.339700Z

So you want to deploy both a backend (the uberjar) and front-end (shadow-cljs)?

solf 2021-02-01T15:02:54.339900Z

An uberjar only needs a server with java installed, you upload the jar by any method and do java -jar uberjar-name.jar. For the frontend, it depends on your app: - either it's served by the backend, in which case it would be already in the jar or somewhere in the same server - it's only static files talking to your server API, in which case you can put them on a cdn, on a server behind nginx (or similar), etc... Frankly, "deploy to the web" is very vague, can't help more than that

solf 2021-02-01T15:04:11.340100Z

You should ask another question describing more precisely what you're trying to do. In another thread, because it's 11PM for me and I'm going to bed πŸ™‚

Henry 2021-02-01T15:07:24.340300Z

That's very helpful already. Really appreciate your help at this hour. Following the docs, I already have a working demo on development mode, but crossing the chasm from dev to prod is a bit vague to me since I am not familiar with how JVM deployment looks like. Good idea to start another thread later with more precise question. Have a good night! πŸ™‚

solf 2021-02-01T08:21:36.329200Z

For clojurescript, shadow-cljs is usually the recommended way. It makes integration with the npm ecosystem (almost) transparent. - https://github.com/thheller/shadow-cljs - https://shadow-cljs.github.io/docs/UsersGuide.html - #shadow-cljs

Marcus 2021-02-01T09:35:26.330300Z

Anyone got this message when using deps.edn to include a git repo? Error building classpath. Destination path "<repo name>" already exists and is not an empty directory

Eamonn Sullivan 2021-02-01T09:39:07.330400Z

Yes, that's a common error. I usually just rm -rf ~/.gitlibs and try again, but apparently you can also try -Sthreads 1 on the command line. The developers think it might be contention between download threads.

Marcus 2021-02-01T09:47:16.330600Z

Ah nice! Thanks. That was the directory I was looking for

Mehdi H. 2021-02-01T10:46:34.330900Z

Is no one interacting using ftp or is my lack of profile picture detrimental to getting any feedback πŸ™‚ ?

2021-02-01T13:41:28.331800Z

gotcha, 1. [SPC w v] to add window vertically 2. [SPC b B] to select the cider REPL poof we got buffer & REPL side by side vertically

1πŸŽ‰
2021-02-01T13:50:21.336700Z

I'm so happy right now πŸ˜„ within 3 day, I successfully : 1. installed DOOM emacs 2. at least know/pretty familiar with the navigation (key combinations) 3. Start REPL after some errors 4. Create a project & connect 2 ns inside 5. move on after stuck at ch 6 in http://braveclojure.com Thank you so much, for the support... I'll learn more, dig more

12πŸ‘1πŸ’ͺ
pavlosmelissinos 2021-02-01T14:04:58.337300Z

FYI most of the time you don't even need the REPL buffer in the foreground

Henry 2021-02-01T14:24:08.338Z

@dromar56 Thanks for sharing. Shadow-cljs is indeed a fantastic tool for CLJS development and deployment. Do you use shadow-cljs with any other build tool for compiling CLJ, like into a uberjar, etc.?

solf 2021-02-01T14:39:17.338200Z

shadow-cljs is cljs-only. For clojure the two options are either - lein (battery included, but falling more and more out of favor) - or deps.edn, the offficial tool (https://clojure.org/guides/deps_and_cli) I prefer deps.edn, but it's pretty barebone. Building a jar with lein is simple:

lein uberjar
With deps.edn, you need to use something like depstar (https://github.com/seancorfield/depstar) Also interesting read if you want to use deps.edn: https://github.com/seancorfield/dot-clojure

solf 2021-02-01T14:41:31.338900Z

TFW people new to (doom-)emacs have a much nicer looking config than mine after 10 years of tweaks. But vanilla4ever

2πŸ‘
Henry 2021-02-01T14:42:48.339200Z

Thanks a lot for helping. If you won't mind sharing, after you've got the frontend codes from shadow-cljs and the uberjar, how do you deploy to the web?

clyfe 2021-02-01T14:56:31.339400Z

Or Prelude?

solf 2021-02-01T14:59:58.339700Z

So you want to deploy both a backend (the uberjar) and front-end (shadow-cljs)?

solf 2021-02-01T15:02:54.339900Z

An uberjar only needs a server with java installed, you upload the jar by any method and do java -jar uberjar-name.jar. For the frontend, it depends on your app: - either it's served by the backend, in which case it would be already in the jar or somewhere in the same server - it's only static files talking to your server API, in which case you can put them on a cdn, on a server behind nginx (or similar), etc... Frankly, "deploy to the web" is very vague, can't help more than that

solf 2021-02-01T15:04:11.340100Z

You should ask another question describing more precisely what you're trying to do. In another thread, because it's 11PM for me and I'm going to bed πŸ™‚

Henry 2021-02-01T15:07:24.340300Z

That's very helpful already. Really appreciate your help at this hour. Following the docs, I already have a working demo on development mode, but crossing the chasm from dev to prod is a bit vague to me since I am not familiar with how JVM deployment looks like. Good idea to start another thread later with more precise question. Have a good night! πŸ™‚

Mehdi H. 2021-02-01T15:20:41.340500Z

-_-'....

GJ 2021-02-01T15:32:27.340700Z

This rings a bell... I followed the direction for the aliases and it didn't work.

GJ 2021-02-01T15:33:00.340900Z

(Checking my notes) The first command to use is clojure -A:new app practicalli/simple-api-server which doesn't work, because we have to install the clj-new project. This is done by updating ~/.clojure/deps.edn and adding an alias Note that copying and pasting the example from the readme doesn't work {:aliases {:new {:extra-deps {seancorfield/clj-new {:mvn/version "1.1.234"}} :exec-fn clj-new/create :exec-args {:template "app"}}} ...} But this does: :aliases { :deps {:extra-deps {org.clojure/tools.deps.alpha {:mvn/version "0.9.857"}}} :test {:extra-paths ["test"]} :new {:extra-deps {seancorfield/clj-new {:mvn/version "1.1.234"}} :exec-fn clj-new/create :exec-args {:template "app"}} } Sorting this out was interesting (something to do with the curly braces).

kpav 2021-02-01T16:38:03.341400Z

just install doom-themes and/or doom-modeline !

javahippie 2021-02-01T16:59:22.347100Z

I am trying to connect my Clojure applications with an APM tool, that traces some variables and the execution time of functions in a nested way. So the HTTP call is the top span, then there are three SQL statements which are child spans, and so on. I created a function to wrap the calls I’d like to trace, and it’s at least working, but I wonder what the best and most idiomatic way would be. My initial approach was to return both the result and a trace-event (a map containing all the info) from each function and collect and send the events in the end, but this feels rather clumsy. Also, if something in the process chain there is an exception, I will lose trace events. Another way could be to pass a β€œsend trace event” callback into the functions I want to trace, and invoke the callback from the inside. Which one would you prefer? Or are there other ways I am not thinking about?

2021-02-01T17:10:51.347300Z

a classic lispy approach is to make wrapper functions that have identical return value but also trace your info:

(defn wrap-trace
  [f]
  (fn [&amp; args]
    (some-tracer-pre f args)
    (let [res (apply f args)]
      (some-tracer-post f args res)
      res)))
that way you never need to mix tracing code into your other logic

1πŸ‘
2021-02-01T17:12:26.347500Z

so if you have foo, you can call (wrap-trace foo) to get a traced function with the same behavior in some cases you might want (alter-var-root #'foo wrap-trace) which replaces the root binding, but often you'd also want to attach the old value of foo to the var metadata (eg. think about what happens if you wrap a function that was already wrapped)

javahippie 2021-02-01T17:13:24.347800Z

Then the first step was right, I have such a wrapper function. And it would be okay to invoke side effects in that wrapper? There would be no other way really, would it?

2021-02-01T17:14:04.348100Z

right, that's the only way to do it - I assume that at the root your tool requires some mutation or side effect to work

2021-02-01T17:14:46.348300Z

also, you mentioned exceptions - so you'd want to use try around the let body, likely with a special cleanup call in the catch

javahippie 2021-02-01T17:14:54.348500Z

Yes, it’s sending network requests.

javahippie 2021-02-01T17:15:10.348700Z

Thanks for the answer, that helped! πŸ‘

2021-02-01T17:15:50.348900Z

yeah - the cleanest way is if the individual usages of the API can remain idempotent, then the only side effect needed is the network request invoked from each wrapper, but you might end up needing client side coordination, in which case a thread plus a queue is probably simplest

javahippie 2021-02-01T17:19:38.349100Z

That shouldn’t be a problem, it is the same request every time, with similar data, and there is already a java lib that handles all the calls non-blocking