Fork me on GitHub

Is there a way to setup default :jvm-opts on deps.edn? It seems you can only do it under an alias


@dromar56 There is currently no way to have a default set of JVM opts.


I'm curious about your use case? I don't see how you'd always want the same JVM opts no matter what aspect of the project you're running?


I don't actually have a use-case that requires it. But I also very seldom use jvm options (I think today was the first time I used them for something other than setting the heap size). When I tried searching for how to set it using deps.edn, I found you could set them using :jvm-opts through an alias, but I didn't expect it would the only way.


Without prior knowledge about when/how someone would want to use jvm opts, I assumed that it also worked as a top level option. This is actually related to an issue I have with the documentation of deps.edn: there's no succinct reference to it. I've read the manual on, but most of the time I already know how to use it (more or less) and am just trying to find the exact syntax to do it. With leins, I used this: I haven't found an alternative to deps.edn, and that made my discovery that :jvm-opts is only an alias setting more difficult than it could have been


From the deps/CLI reference page: "JVM arguments may either be passed on the command line (with -J) or by using data stored in an alias under :jvm-opts and passed with -X or -A or -M" and also "The configuration file format (in deps.edn files) is an edn map with top-level keys :deps, :paths, and :aliases, plus provider-specific keys for configuring dependency sources." -- so it says there are three top-level keys and it also says :jvm-opts can be stored in an alias. I guess if you have suggestions for making it clearer, you could post that on


The closest equivalent to Leiningen's sample.project.clj is the example-deps.edn in the CLI install, which is copied to ~/.clojure on first use (and also remains in the installation). But that currently refers to -R and -C options which are both deprecated (or maybe even removed at this point). And it does not show :jvm-opts... I'll post a Q on about that...


Thanks a lot!


@dromar56 One thing you could do is use a shell alias, for any options to clj that you use very frequently while developing


good morning all

😃 1

any shadow-expert who can help me with this How to solve this one :

cljs꞉cljs.user꞉>  @state/orders
; No available JS runtime.
clj꞉cljs.user꞉>  @state
{:source-paths ["src"]

 :dependencies [[binaryage/devtools "0.9.10"]
                [proto-repl "0.3.1"]
                [reagent "0.8.0"]]

 :nrepl        {:port 3333}

 {:app {:target :browser
        :output-dir "public/js"
        :asset-path "/js"

         {:entries [giggin.core]}}

        {:after-load  giggin.core/main
         :http-root   "public"
         :http-port   3000}}}}


The repl needs to something that runs js so it can run stuff


Since you're targeting a browser, you need to open the browser


Localhost:3000 it seems.


I just found out that the Duffer brothers (stranger things) were from Durham NC. What is it that makes people from Durham special?


I think it's the Cheerwine


Sounds appealing. They have cherry beer here in Belgium.


also good! :)


Having just moved to the area recently, I suspect it may also have to do with the vinegar based barbecue, which I never heard of before:;


@hobosarefriends I have a browser open


if you do (js/alert "test") does the alert window pop up?


(have you made sure that nothing else is running on that port?)


yep, I see then a popup with the text test on it on my browser


huh… then it is connected.. that’s pretty weird


maybe ask in #shadow-cljs


no probs, sorry I couldn’t solve it


it is solved


I had to use the namespace before the call


stupid beginners error


Good to hear my dude, and you seem to understand why it happened so that’s even better.


yep I understand now after soeme help of the shadow-cljs channel

Claudio Ferreira14:01:03

Study Algo & Data Struc. in Java will help me become a better Clojure dev?


studying algo and data structures in any language will usually help you become a better developer in every other language you use

👍 6

I agree with @dpsutton,I work with devs where everything is either an object (as in C# object or a string, and every data structure is list. Then they wonder why everything is so slow. Learning data structures and algorithms will never not be a good idea.

Sibelius Seraphini15:01:19

is there a prettier for clojure?

Sibelius Seraphini15:01:49

I’ve found this, but not sure how to run this in a cli to pretty print my code


there is also an awesome zprint library


I have once seen a nice youtube? demo of clojure where the presenter is counting words of moby dick to demonstrate clojure. Does anyone know what I'm talking about?


Yes, James did some great live coding sessions like this a while ago, great to bring them together. I did a short version of one of his examples to show how to use Cider and the Cider inspector

👀 1

So is there something special I have to do to make sure my clojure / lein program can access all my linux box environment variables? I am trying to run google translate on my remote box and I keep getting 403 invalid API key even though I have run export GOOG_APP_CREDS = /path/to/file ... the api key works on my local box ;/


System/getenv can see everything that your process sees, it shouldn't even be an issue on the java / clojure side


That's what I was thinking.


for debugging: (pprint (into {} (System/getenv)))


it might be that it needs the System property to be set

🙌 1

or that it's using some config instead of the environment


depending on how you start an application, it may not be running your shell startup environment

💯 2

gasp. is no there in the pprint list.


"export" is for the current shell and child shells, you need the export to happen in the parent of the java process - I usually prefer to add the env var as a prefix on the java command itself


Hmmm okay... what's that look like?


FOO=bar java ...


or env $(cat env_file) java ...


you saved me a lot of headscratching


maybe 2 miles worth of headscratching if calculated by finger travel

😂 2

you can also access the environment of other processes if you have permission

user=> (-> (slurp "/proc/self/environ") (s/replace (String. (byte-array [0])) "\n") println)


("self" is the magic directory for the current pid, you can use an arbitrary pid there)


How do you deal with async methods in repl based development? Let's say I have a method that returns immediately and calls a callback when done, I can't evaluate it in the repl because I won't be able to access what is passed to the callback

Daniel Stephens20:01:55

You could always setup a function (I've called mine spy) that is able to wrap any other function and logs inputs and outputs. No reason you couldn't also get it to reset! some atoms of input and output if it's not a nice readable results.

(defn spy [f]
  (fn [& args]
    (println "--------------------------")
    (println "calling callback" f "with:")
    (clojure.pprint/pprint args)
    (println "--------------------------")
    (let [o (apply f args)]
      (println "--------------------------")
      (println "callback" f "returned:")
      (clojure.pprint/pprint o)
      (println "--------------------------")
=> #'user/spy

(defn async-method [millis callback-fn]
    (Thread/sleep millis)
    (callback-fn millis)))
=> #'user/async-method

(defn callback [millis] (println "In callback after" millis))
=> #'user/callback

(async-method 1000 (spy callback))
        {:status :pending, :val nil}]
calling callback #object[user$callback 0x4ac10f16 [email protected]] with:
In callback after 1000
callback #object[user$callback 0x4ac10f16 [email protected]] returned:

Daniel Stephens20:01:24

oops, just seen this is basically what was already suggested in another thread!


@ggfpc12495 you can call def, or deliver to a promise, or swap! on an atom


(cmd)user=> (def p (promise))
(ins)user=> (.start (Thread. (fn [] (Thread/sleep 10000) (deliver p 42))))
(ins)user=> @p


that ten second delay should be long enough to see the pause happen in a repl


@ggfpc12495 if your app design is consistently async, core.async can help keep things a little simpler (but it also imposes a number of constraints)


Your approach makes sense to me, but then are we not changing our code to fit a specific development process?


I don't have much experience with Lisps but it feels weird coming from a Java world to do that


java is full of bizarre "patterns" that shoehorn models into a dev process


@ggfpc12495 on a slightly less glib note, clojure does tend to encourage a specific kind of design that makes repl usage easier, but in most cases this can be done in a way that is also decoupling concerns


the real thing to avoid is coupling things because it makes dev simpler without regard for your domain (DI / factories etc. can do this as easily as decomposing for repl usage does)


your adaptor might look like a function that takes a callback and returns a new one that also sets a promise, for example


Thanks will look into your suggestions


here's a minimal function which takes a promise and a callback, and creates a new cb that captures the value the callback sees

(ins)user=> (defn tracked-cb [p f] (fn [& args] (deliver p args) (apply f args)))
(ins)user=> (defn printing-cb [x y] (println "callback:" x y))
(ins)user=> (def p (promise))
(ins)user=> (def cb (tracked-cb p printing-cb))
(ins)user=> (.start (Thread. #(cb :a :b)))
user=> callback: :a :b

(ins)user=> @p
(:a :b)
in general a lot of mocks / stubs / dependency injections can be replaced with regular functions


a promise (as a let binding rather than a def most likely) can similarly be used in tests - dual benefit that the value isn't ready until the promise is delivered to so the test won't do its comparison until the async result is ready


are there more free courses . I find this one also a lot about clojure and not much about components and so on

Sibelius Seraphini20:01:57

I’m trying to make log/info and log/debug to show in my terminal, but I’ve got this error: ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console... this is the code/project


java logging config is severely brittle and counterintuitive, the big picture answer is "you need to pick a logger, configure it, and ensure code you care about is hooked up to it", but the specifics are full of gotchas. The best answers will probably be java specific in presentation.


the two stable outcomes I've seen are "magic .properties fill in resources that nobody touches" and "complex code that nobody touches"


You need to look at the deps tree, but my guess is something is pulling in log4j2, and tools.logging is defaulting to using that, where it looks like the project is trying to use logback

Sibelius Seraphini20:01:51

is there a simple print or console.log (from js) but in clojure?

Sibelius Seraphini20:01:04

I just wanna introspect some variables to understand this code


There are many


prn or println are maybe the most common


*out* gives you access to a PrintWriter that writes to stdout by default, *err* to stderr

👍 1

Hello, are records in use in the wild or maybe maps are more popular these days?


there's a really good flowchart about this, but the tl;dr is that everything is designed so you can write code using maps, and convert to records / types / generated classes etc. when you know you need it


It's worth noting that Clojure Applied talks up records fairly heavily but the author (Alex Miller) has said that if they do a 2nd Ed he would deemphasize records quite a bit and lean more heavily on plain hash maps.


Records are in use in the wild, and maps are more popular, there are good reasons for both. Use maps, and switch to records when you have millions of maps with the same keys.