beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
dharrigan 2020-09-10T06:32:54.046900Z

@alexmiller Hi, thanks for the update. Yes, just the line at the bottom should read the root value has already been reset back to 42, potentially causing a race condition instead of the root value has already been reset back to 0, causing a race condition

Grigory Shepelev 2020-09-10T06:59:54.049900Z

Good day everyone. I'm writing gui application with cljfx and it works on multimethod. I have the following structure.

(defmulti handle ::event)
(defmethod handle ::analyze (…))
(defmethod handle ::try-load-file (…))
And I want to catch all the exepctions of my method in a multimethod and show an alert window with exception info. But the first question is how can I do that in general. It's got to be something like this:
(defmulti handle
  (fn [event]
    (try (event)
         (catch Exception e (str e)))))
Although it doesn't works because event is passed as something evaluated already.

Grigory Shepelev 2020-09-10T07:00:31.050200Z

A little help?

Grigory Shepelev 2020-09-10T07:03:08.051300Z

Or the multimethod can be bad idea in given case. If some correction would be given - it would help a lot

2020-09-10T07:08:18.051600Z

@altjsus I'm not sure what you're trying to do

2020-09-10T07:08:35.052Z

You want to catch exceptions that your handle methods could throw?

2020-09-10T07:11:25.054Z

If so, I would do this:

(defn try-handle [...]
  (try
    (handle ...)
    (catch (Exception e) (str e))))

(defmulti handle ::event)
(defmethod handle ::analyze (...))
(defmethod handle ::load-file (...))

2020-09-10T07:12:05.054600Z

And I'd have your callers call try-handle instead of handle

baptiste-from-paris 2020-09-10T07:14:16.056800Z

IMO, you don’t want to throw or catch exception in the dispatch fn as it will try to find a dispatch method. Even with your str it will throw an exception (NullPointerEx) If you look at MultiFn.java from clojure source code you’ll find :

public Object invoke(Object arg1) {
	return getFn(dispatchFn.invoke(arg1)).invoke(Util.ret1(arg1,arg1=null));
}

baptiste-from-paris 2020-09-10T07:15:45.057900Z

which means that the dispatchFn has to find some defmethod to call invoke again

0xclj 2020-09-10T07:20:12.058300Z

Hi, I'm looking for a code-flow visualizer for clojure. Something similar to http://www.pythontutor.com/visualize.html#mode=edithttp://www.pythontutor.com/visualize.html#mode=edit. Any pointers would be much appreciated. Thanks!

0xclj 2020-09-13T07:23:18.159900Z

@didibus https://github.com/vlaaad/reveal looks relevant

baptiste-from-paris 2020-09-10T07:28:08.058700Z

you could have a default value for your dispatch and handle exception on a per-method basis

(defmulti yeahhh (fn [o] o))

  (defmethod yeahhh :default [event] (pr "called when no defmethod was found"))
  (defmethod yeahhh :a [event]
    (try (throw (ex-message "Ex"))
         (catch Exception e (str "Handled") )))

  (yeahhh :a)

2020-09-10T07:30:17.059100Z

Hum, I don't know of any web based ones, but Emacs, Cursive and I believe VSCode with Calva all have debuggers that allow you to step through code and see the value of every variable and the result of every evaluation as you step through the code

2020-09-10T07:31:34.059300Z

There's some library also that do this a bit more "manual" I think they normally refer to this as tracing, for example https://github.com/clojure/tools.trace

2020-09-10T07:34:05.059700Z

And I remember of https://github.com/dgrnbrg/spyscope and https://github.com/clojure-emacs/sayid

2020-09-10T07:35:30.060300Z

Here's the guide for VSCode with Calva: https://calva.io/debugger/

0xclj 2020-09-10T07:40:40.060700Z

I'm primarily looking for something web based where I can trace the code flow line by line. The only visualizer I have been able to find so far is a block-visualizer - http://lincoln-b.com/blocks/ I did install Calva just a while ago. Will go through it and will check out the other libraries as well. Thank you!

2020-09-10T07:43:43.060900Z

I don't know of a web based one. Could be an interesting project!

2020-09-10T07:46:34.061200Z

Hum, its not ideal, but since your link supports JavaScript. You can first convert the ClojureScript code to JS with this: http://app.klipse.tech/ and then paste the JS in your python tutor link

Grigory Shepelev 2020-09-10T08:13:31.062400Z

Are there anyone who has some experience with cljfx?

0xclj 2020-09-10T08:15:34.062500Z

I have Clojure code actually. Haven't explored ClojureScript yet.

practicalli-john 2020-09-10T08:47:22.062700Z

The #cljfx channel seems active

Timofey Sitnikov 2020-09-10T11:13:14.065Z

Good morning Clojurians. I am trying to figure out how to serve static files based on this document: https://cljdoc.org/d/metosin/reitit/0.3.10/doc/ring/static-resources. Here is the code I have

(ns sandbox.main
  (:require [reitit.ring :as ring]
            [ring.adapter.jetty :as jetty]))

(def app
  (ring/ring-handler
    (ring/router
      ["/ping" (constantly {:status 200, :body "pong"})])
    (ring/routes
      (ring/create-resource-handler {:path "/" :root "public"})
      (ring/create-default-handler))))

(defn start []
  (jetty/run-jetty #'app {:port 3000, :join? false})
  (println "server running in port 3000")) 
I have placed an index.html file under project_root/public , but I keep getting HTTP/1.1 404 Not Found What can i be doing wrong? Below is the output, notice that the ping request gets the pong reply.
[I] /home/sporty/clojure~> http localhost:3000/ping
HTTP/1.1 200 OK
Content-Length: 4
Date: Thu, 10 Sep 2020 11:14:24 GMT
Server: Jetty(9.4.28.v20200408)

pong

[I] /home/sporty/clojure~> http localhost:3000/index.html
HTTP/1.1 404 Not Found
Content-Length: 0
Date: Thu, 10 Sep 2020 11:14:30 GMT
Server: Jetty(9.4.28.v20200408)

jsn 2020-09-10T11:19:22.065300Z

I don't know much about ring, but shouldn't it be project_root/resources/public ?

Timofey Sitnikov 2020-09-10T11:26:47.065600Z

I tried the following locations:

project_root/public
project_root/resources/public
project_root/src/resources/public

teodorlu 2020-09-10T11:58:33.065900Z

I recently struggled with the arguments to the Compojure equivalent to ring/create-resource-handler too. I ended up avoiding the issue by not passing arguments. By default, it mounts resources/public to "/". I then put my static files in a subdirectory that gave me the path I wanted.

cgrand 2020-09-10T12:09:45.066800Z

@timofey.sitnikov I believe it looks for the resource on the classpath

cgrand 2020-09-10T12:10:23.067300Z

so move your file under project_root/resources/public/

teodorlu 2020-09-10T12:16:44.068400Z

@timofey.sitnikov note also that you're referring to docs for an old version (0.3.10) of Reitit. Docs for the latest version (0.5.5): https://cljdoc.org/d/metosin/reitit/0.5.5/doc/ring/static-resources

Timofey Sitnikov 2020-09-10T12:32:56.068600Z

OK, got it, deps.edn must include the resources` directory like so: :paths ["src" "resources"], the static files do need to be in the project_root/resources/public, and the path parameter is required like so (ring/create-resource-handler {:path "/"})

Timofey Sitnikov 2020-09-10T12:33:18.068800Z

Thank you @teodorlu and @jason358

1πŸ‘
2020-09-10T14:04:56.070100Z

Can someone help me understand the syntax of for in this toy code example? Why is it that let binding becomes a keyword :let:

(for [x (range 1 6)
      :let [y (* x x)
            z (* x x x)]]
  [x y z])

alexmiller 2020-09-10T14:05:56.070700Z

:let is a special modifier understood by for (`for` is a macro and basically has its own syntax)

1
2020-09-10T14:05:57.070800Z

I mean I understand this is how it just is but curious about why the modifiers turn into keywords if it’s not too esoteric.

2020-09-10T14:06:30.071Z

Ahh cool.

seancorfield 2020-09-10T15:53:34.071900Z

@rosschapman doseq supports the same syntax as for -- with :let, :when, :while

2
Grigory Shepelev 2020-09-10T17:15:35.075600Z

Good day. I'm trying to make an uberjar of my project. It runs perfectly with lein run but, lein uberjar hangs (> 30 minutes) and lein jar creates a jar but trying to run like leads to java.lang.ClassNotFoundException any ideas?

dpsutton 2020-09-10T17:19:05.076300Z

do you have any top level expressions that do lots of work? long running jobs, infinite loops working on queues and such?

1πŸ‘†
Grigory Shepelev 2020-09-10T17:30:12.077200Z

I mean: why would it work with 'lein run'?

Grigory Shepelev 2020-09-10T17:30:29.077600Z

Guess not

dpsutton 2020-09-10T17:31:57.078400Z

because lein run spins up an interactive long-running process and you want these long running things. if you are compiling you don't want these long running processes.

Grigory Shepelev 2020-09-10T17:45:20.078900Z

Hm I will try tomorrow. Thanks for the hint

Joel 2020-09-10T18:04:55.081Z

(def s [ [[:a :b] 'x] [[:c :d] 'y] ])
(mapcat (fn [[l e]] (map #([% e]) l)) s)

Joel 2020-09-10T18:05:59.081600Z

I get args(0) passed to PersistentVector?

dpsutton 2020-09-10T18:06:01.081700Z

check (macroexpand '#([% e]))

dpsutton 2020-09-10T18:06:23.082100Z

(fn* [p1__439923#] ([p1__439923# e])) is the result and its invoking your vector

dpsutton 2020-09-10T18:06:50.082700Z

(macroexpand '#(inc %)) -> (fn* [p1__439927#] (inc p1__439927#))

Joel 2020-09-10T18:07:06.083100Z

is macroexpand the right way, did i go about this the wrong way?

Joel 2020-09-10T18:07:27.083600Z

looking for

{:a 'x :b 'x :c 'y ...}

dpsutton 2020-09-10T18:08:15.084600Z

no, i'm saying macroexpand will show you what your anonymous function is turning into #([% e]) is a function (fn [thing] ([thing e])) which is invoking the vector with no args

1πŸ™‚
dpsutton 2020-09-10T18:09:06.085100Z

not related to your logic, but just not doing what you want

Joel 2020-09-10T18:14:34.085500Z

thanks, that was confusing, didn't know to try macroexpand

1πŸ‘
dpsutton 2020-09-10T18:15:03.085900Z

its a common mistake. everyone has gone through that one πŸ™‚

Joel 2020-09-10T18:19:50.086400Z

i presume (into {}) is non-lazy?

dpsutton 2020-09-10T18:20:39.086800Z

correct. but there's no way to lazily build a map in any context

alexmiller 2020-09-10T18:21:29.087100Z

maps are a concrete data structure and always fully realized

2020-09-10T18:30:03.087700Z

clojure is a strict language, it is never lazily evaluated (or non-strictly) like say haskell

2020-09-10T18:31:19.087900Z

there are some technicalities to this, lazy-seqs are a strictly constructed lazy data structure, but there is no lazy evaluation

v 2020-09-10T18:37:07.088400Z

Hello, whats the best way to manage environment variables in deps.edn project

alexmiller 2020-09-10T19:08:22.088800Z

how do environment variables impact deps.edn?

seancorfield 2020-09-10T19:13:01.089600Z

@vishal.gautam You can set JVM properties in deps.edn but environment variables are outside the scope of setting up and running a (Clojure) process.

paulocuneo 2020-09-10T21:03:02.091500Z

;; if you want to load properties from a file (java style)
(defn load-props [f]
  (let [in (io/input-stream f)
        updated-props (.load (System/getProperties) in)]
    (.close in)
    (System/setProperties updated-props)))
(load-props "my.properties")
;; then access the property like,
(System/getenv "a-property-name")
;; System/getenv works with any env var

practicalli-john 2020-09-10T23:50:09.093800Z

Environment variables are used directly by the Clojure application. Evaluating (System/getenv)`` will return a map of all environtment variables. The function will also read in a specific environment variable

(System/getenv "PORT")
Use the aero library to define all configuration in one file, including which environment variables to use across multiple environments, e.g. dev, staging, live https://github.com/juxt/aero

practicalli-john 2020-09-10T23:51:59.094100Z

As others have mentioned, Java properties files can also be used to configure the Java Virtual Machine https://practicalli.github.io/clojure-webapps/app-servers/java-system-properties.html