Fork me on GitHub
#beginners
<
2020-09-10
>
dharrigan06:09:54

@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 Shepelev06:09:54

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 Shepelev07:09:08

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

didibus07:09:18

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

didibus07:09:35

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

didibus07:09:25

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 (...))

didibus07:09:05

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

baptiste-from-paris07:09:16

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-paris07:09:08

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)

baptiste-from-paris07:09:45

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

0xclj07:09:12

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!

didibus07:09:17

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

didibus07:09:34

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

didibus07:09:30

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

0xclj07:09:40

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!

didibus07:09:43

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

didibus07:09:34

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

0xclj08:09:34

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

Grigory Shepelev08:09:31

Are there anyone who has some experience with cljfx?

practicalli-johnny08:09:22

The #cljfx channel seems active

Timofey Sitnikov11:09:14

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)

jsn11:09:22

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

Timofey Sitnikov11:09:47

I tried the following locations:

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

teodorlu11:09:33

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.

Timofey Sitnikov12:09:56

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 "/"})

cgrand12:09:45

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

cgrand12:09:23

so move your file under project_root/resources/public/

teodorlu12:09:44

@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

Ross Chapman14:09:56

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])

Ross Chapman14:09:57

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.

Alex Miller (Clojure team)14:09:56

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

thanks3 3
seancorfield15:09:34

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

thanks3 6
Grigory Shepelev17:09:35

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?

dpsutton17:09:05

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

👆 3
Grigory Shepelev17:09:12

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

dpsutton17:09:57

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 Shepelev17:09:20

Hm I will try tomorrow. Thanks for the hint

Joel18:09:55

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

Joel18:09:59

I get args(0) passed to PersistentVector?

dpsutton18:09:01

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

dpsutton18:09:23

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

dpsutton18:09:50

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

Joel18:09:06

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

Joel18:09:27

looking for

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

dpsutton18:09:15

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

🙂 3
dpsutton18:09:06

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

Joel18:09:34

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

👍 3
dpsutton18:09:03

its a common mistake. everyone has gone through that one 🙂

Joel18:09:50

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

hiredman18:09:03

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

hiredman18:09:19

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

dpsutton18:09:39

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

Alex Miller (Clojure team)18:09:29

maps are a concrete data structure and always fully realized

Vishal Gautam18:09:07

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

practicalli-johnny23:09:09

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-johnny23:09:59

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

Alex Miller (Clojure team)19:09:22

how do environment variables impact deps.edn?

seancorfield19:09:01

@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.

paulocuneo21:09:02

;; 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