Fork me on GitHub

Running into problem running lein repl inside container. On OSX works as expected, but on WSL2 somehow getting clj-container exited with code 0 . I have project.clj, where I run one function (launching mount). Expected behaviour that happens on mac is that repl opens port, runs the code defined in project.clj and keeps on waiting. Exit is happening on WSL2 - no idea why it exits. When I run solo container with term attached (outside compose) it run fine.


Ok, if anybody runs into the same show. Running lein repl :headless solves the deal. I am betting its something regarding said terminal attachment. Thanks for reading my story 🙂


(list? (a b c)) ;; => false`


dev=> (type `(a b c))
So it's not a list.


list? is a really weird predicate that pretty much no one uses.


dev=> (list? (map identity '[a b c]))


(because a LazySeq is not a list either)


what's the right thing to do here? seq?


What question are you trying to ask?


dev=> (list? (range 3))


sequential? perhaps? seqable? maybe?


I have a definition like this

(def system
    (db {:uri (config :db/uri)})
    (dir-watcher-pool (config :dirs))))


l'd like to walk it and handle all structures of the form (<sym> <args>)


I naively thought (and (list? x) (symbol? (first x))) would suffice


dev=> (doseq [l [() '(a b c) `(a b c) (map identity '[a b c]) (range 3)]
 #_=>         p [list? seq? seqable? sequential?]]
 #_=>   (println (type p) l (p l)))
clojure.core$list_QMARK_ () true
clojure.core$seq_QMARK___5471 () true
clojure.core$seqable_QMARK_ () true
clojure.core$sequential_QMARK_ () true
clojure.core$list_QMARK_ (a b c) true
clojure.core$seq_QMARK___5471 (a b c) true
clojure.core$seqable_QMARK_ (a b c) true
clojure.core$sequential_QMARK_ (a b c) true
clojure.core$list_QMARK_ (dev/a dev/b dev/c) false
clojure.core$seq_QMARK___5471 (dev/a dev/b dev/c) true
clojure.core$seqable_QMARK_ (dev/a dev/b dev/c) true
clojure.core$sequential_QMARK_ (dev/a dev/b dev/c) true
clojure.core$list_QMARK_ (a b c) false
clojure.core$seq_QMARK___5471 (a b c) true
clojure.core$seqable_QMARK_ (a b c) true
clojure.core$sequential_QMARK_ (a b c) true
clojure.core$list_QMARK_ (0 1 2) false
clojure.core$seq_QMARK___5471 (0 1 2) true
clojure.core$seqable_QMARK_ (0 1 2) true
clojure.core$sequential_QMARK_ (0 1 2) true


essentially I want something that is either a list or a cons


But not a vector? sequential? will be true on a vector.


that's right


guess I'll check the type


Several of those predicates test instance? so you need to know what the underlying type hierarchy is.


oh and postwalk converts it to a lazyseq


so I guess I was doomed from the start


In HoneySQL I just used sequential? and allowed lists or vectors... maybe seq? will be enough for your use case? (it's false on vectors)


(but I think there are cases where you get something list-like that is not seq? but I can't remember)


Clojure persistentlists are also seqs


By which I mean seq? should have you covered


yeah I'll go with that


I realize that I’m late, but just to add to it… Clojure will eval things that return true for a seq?, so this looks to align with what you want

jeff tang08:02:48

How come Clojure keywords only support up to one level of namespaces? Like why can’t I do :clojure/community/slack and :clojure/community/zulip


usually one would use java style "package" names separated by dots


like :some.deep.ns/a-key


I think you can make them using keyword but can’t read them (keyword "what/is/happening?");; => :what/is/happening?

jeff tang08:02:55

Indeed, that is how Clojure package namespaces work as well e.g.: app.views.button Why not always use the period as the delimiter then if slashes can only be used once?


you can destructure keys in an ns { [a-key other-key]}


and it mirrors how vars work, some.deep.ns/some-var


you can access the namespace and name parts separately, but I guess nothing prevents you from having raw keywords with just dotted names

👍 1

> Why not always use the period as the delimiter then if slashes can only be used once? If this were true, would a.b.c be a namespace in file a/b/c.clj or a var c in namespace a.b? With slashes delimiting namespaces from their contents it's clear for both the user and the machine.

jeff tang11:02:51

it's ironic that that there are two concepts of namespaces, colliding in their name and usage


Not sure what you mean.


the dots in namespaces do have a mapping to file paths, but I otherwise I don't think they have any semantic


you could do use :foo-bar-baz/a-key just as easily


I don't see that there are 2 namespaces... it's just that namespace names have some meaning


This could be me just being rusty with clojure but I should be able to create src/promesa/core.cljs and create new macros that are accessible through p/new-macro given (require '[promesa.core :as p]) right?


Was the path really meant to be cljs and not clj ?


Working in cljs but figured it would be the same regardless of host?


It's not the same, alas. In Clojure, you can add macros anywhere - you can even use them in the same file and ns where you define them. In CLJS, that's not the case. If it's not a self-hosted environment, you have to have all your macros in either a .clj file or in a .cljc file (don't do the latter - it's easy to make a hard-to-fix mess). If it's a self-hosted environment, you have to have a .cljs file with your macros but the corresponding ns has to be required with :require-macros.


I'm using nbb so macros are supported the clojure way just trying to understand how to extend the funcool.promesa/core ns


I would ask in #nbb then. :) No clue what peculiarities that platform might have. But in CLJ, your approach would work. But note that adding a/b.clj to your sources while some jar on your classpath already has a/b.clj will not extend that a.b namespace but simply replace it (assuming src appears on the classpath earlier than that jar).


Wanted to know what the intended behavior was with clojure so that I can understand if nbb is consistent or not. Plus I've been terrorizing that channel with questions lately. Sounds like that approach would not work


Why would you want to add a macro to some existing third-party namespace instead of just using one of your own namespaces, like promesa-utils or whatever?


Developing a macro for an upstream PR but wanted to extend the existing namespace so the naming would be correct and I can update the library, remove my draft version, and everything would still work in my project. I settled for just adding it to my utils.cljs but was curious if there was a better way as it's used across a few files


A better way would be to develop all changes in a custom fork and depend on that fork in your project. And when the upstream lib incorporates your changes, you can just swap the dependency.


This doesn’t work (let did not conform to spec)

(let []
(let []
  (when true
Bug? on 1.10.3


isn't this a case of a conformed value being equal to c.s.a/invalid when the let is validated causing it to fail


iirc you can do (def invalid :clojure.spec.alpha/invalid) and then refer to invalid in your code


should work


it only happens with specced macros iirc


writing a conformer, which is supposed to return :clojure.spec.alpha/invalid on failure.


I’ll go with your way @mpenet and add an explanation to the var, thanks!


A misconfiguration from a client resulted in us getting a load test for free 🙂 From a usual load of max 3req/s, we went to 10req/s. Our CPU usage went to roughly 90-95%. Obviously we adjusted our autoscaling policies, but I'm curious to know what exactly was consuming that much CPU time. Is it possible to generate something like a flamegraph but in production? I'm curious on whether it was logging, printing stacktraces, JSON formatting or something completely different that was spinning...


For something like this we had the FlightRecorder running constantly on Prod. I’m not sure if is possible to analyze the event retrospectively, though Edit: Also might cause a 1-2% performance hit for the app while it’s running


Retrospectively probably not, I wouldn't expect that. Just to be prepared if it happens again, and to establish a baseline.


Oh that's nice. So essentially you would e.g. keep dumping JFR files every, say, hour? Then if you wanted to look into an incident, you would get the JFR file of that hour and see what was the CPU/memory activity plus the stack samples? That's really helpful.


That should be possible via triggers, yes. And afterwards you could read the dump with Misson Control or VisualVM.


CodeGuru seems to do something similar but I can't find if they use JFR behind the scenes or not.


Seems to not have any compile time dependencies at all, so it’s probably their own


If Codeguru aggregates it in a single place, it sounds like the nicer solution for AWS 👍


They might be using which is what the Clojure-goes-fast profiler uses.

Ben Sless19:02:40

You can generate a flame graph in production by embedding clj-async-profiler in your application. Pretty easy

Ben Sless19:02:05

Though you can also run this profiling on you local machine

Ben Sless19:02:45

Moreover, if you collect JVM metrics besides host metrics, check your heap and GC graphs

Ben Sless19:02:03

How did you start and run your application?


Hi. How to achieve the same purpose of a function scoped static initializer in cpp, like this:

void func() {
    // this foo is only initialized once, at the first time when func() is called
    static foo = some_other_func();
    // do some work
I’d like to have some part of logic to be executed only once. Defonce is not relevant here as it pollutes the namespace.


Just so I understand correctly, multiple calls to func do not call some_other_func after the first invocation?


Why doesn't a closure work?


Ah I get it 😅

Zohar Kelrich15:02:17

Is this about right?

(let [foo (delay (some-other-func))]
  (defn func []
     (work-with @foo)))


Probably I shall stop clj-kondo complaining about the defn inside let.


(def func
  (let [foo (delay (some-other-func))]
    (fn [] ...)))

👍 1
Alex Miller (Clojure team)14:02:14

it has the downside of requiring the result to be deref'ed but has the single execution semantics

Zohar Kelrich15:02:47

I think I found a Clojure bug.

(let [v ##NaN] (= v v))
=> false
(let [f #(= % %)]
  (f ##NaN))
=> true
That second one should be false as well, but it's not, because of boxing

😓 1

Why do you say it should be false?


It is true because the values are identical?, as someone explained later. I agree this is surprising, but Clojure's = for efficiency relies on quickly returning true when its two args are identical? (i.e. same object in memory). Making a special case in = to check that they are ##NaN would slow down = for all values.


I agree it is confusing, but not sure I would call it a bug.

Zohar Kelrich15:02:19

Because ##NaN is defined to not equal ##NaN

Zohar Kelrich15:02:31

This means that an "optimization" is incorrect


Use == to compare numbers numerically


user=> (let [v ##NaN] (== v v))
user=> (let [f #(== % %)] (f ##NaN))

Zohar Kelrich16:02:51

This isn't about ==. This is = being too sensitive, and breaking value equality


You can ask. I wouldn't be surprised if the answer from Clojure maintainers is as above, but I am not a Clojure maintainer, so I will let them choose their own answer.


I am only giving you my best educated guess as to the reason. Efficiency is a huge concern for them.


You might want to file a bug against Java, too, while you're at it:

(.equals ##NaN ##NaN)


although that behavior is documented, I believe.


Java numeric comparisons return false for NaN, I believe.


I've filed dozens of bugs in the Clojure core implementation myself over the last 10 years, so I'm not claiming it is all perfect and laid out like holy texts, or anything. Just that sometimes the answer isn't what you want it to be.


That’s interesting

Joshua Suskalo15:02:36

so reference equality short-circuiting is causing the value equality of nan to not be checked? that's interesting


@zohark i’d make a question on with this question. Quite possible its a known issue. But if not, that’s the best place to get thoughtful eyes on it if a fix is warranted


Style question: is there a compelling reason (not) to use letfn vs fn in a let binding? Other than needing to call other functions declared the same way in that set of bindings?

Alex Miller (Clojure team)17:02:34

letfn is a little special in letting you define a function that you can use in a self call (or multiple fns you can call from each other)

Alex Miller (Clojure team)17:02:14

99% of the time you don't need that power and it probably doesn't matter


ok, that’s what I figured… if I don’t need to recurse or call another fn at that level…


a lot of people hate letfn because it has forms like (x ....) where x is not a special form, function call, or macro


I prefer it over let binding functions though, and have no supporting reasoning

metal 2

Elements of Clojure has a section on letfn which basically makes the case against using it unless absolutely needed


There are a lot of features of common lisp that are almost completely unneeded in clojure. This seems like one of them.


I mean, why have it at all, everyone could just write their own


Self recursion can always happen in a let using the optional name? that not everyone seems to be aware of, but the mutual references between functions feature is very cool! 🙂


@U051N6TTC not sure I know what you mean about name? . Could you explain? 😁



(def fib (fn f [n] (if (< n 2) 1 (+ (f (dec n)) (f (- n 2))))))


The use of “f” here is an optional name? argument that can be provided to fn. It allows anonymous functions to refer to themselves.


It shows up in the documentation for fn:

=> (doc fn)
  (fn name? [params*] exprs*)
  (fn name? ([params*] exprs*) +)
([& sigs])
Special Form
  params => positional-params* , or positional-params* & next-param
  positional-param => binding-form
  next-param => binding-form
  name => symbol

  Defines a function

  Please see 
  args: (cat :fn-name (? simple-symbol?) :fn-tail (alt :arity-1 :clojure.core.specs.alpha/params+body :arity-n (+ (spec :clojure.core.specs.alpha/params+body))))
  ret: any?


Ohhh. I was looking under let lol


I think I have seen that feature, but not used it. Yet.

Stel Abrego20:02:45

Hey friends, I have a question about namespaces. I've noticed that many popular Clojure libraries don't use the reverse domain name namespace convention recommended by the Clojure I'm writing a library right now and I'm torn between the easier to remember foobarbaz.api or the fully qualified codes.stel.foobarbaz.api . Is it ok to drop the reverse domain name if the libary has a fairly unique name? Also, I would like to group all of the public API into a single namespace. From what I can tell, common names for such a namespace are api, interface, and core. I'm leaning towards api, like Datomic. Any reason I shouldn't?


Is that a packaging concern or the API? Because you can ship your package under fully qualified name, but your namespaces do not have to use that format


So your maven coordinates can be codes.stel/foobarbaz but your namespaces only use foobarbaz


it is nice to having something that’s a bit identifiable to you so that namespaces don’t collide when required


for me i’d use dpsutton.foobarbaz just incase someone else has a really helpful foobarbaz library and then also think they should take that top level

Stel Abrego20:02:18

@U0JEFEZH6 That's a good point. I'm planning on using codes.stel/foobarbaz as the maven coordinates. I was mostly wondering about the namespace collision issue.


for instance stuart sierra’s component library has coordinates

com.stuartsierra/component {:mvn/version "1.0.0"}
and namespace
Personally i would have just used stuartsierra.component for the ns. But you can see the danger had he just named his namespace component. Single segment namespaces are heavily discouraged for this reason

Stel Abrego20:02:52

@U11BV7MTK Ah yes that makes sense, I feel like even component.core would be a collision risk. I'm leaning towards using fully-qualified namespaces.


reverse domain guarantees uniqueness if you own the domain


is the diff


as opposed to, “probably fine”


Nothing prevents me from putting namespaces with others reverse dns though, right?

truestory 1
😿 1

@U019RSW97UZ "I'm planning on using codes.stel/foobarbaz as the maven coordinates." -- I assume you own a domain and can verify that for the Clojars team? See

Stel Abrego21:02:01

@U04V70XH6 Hey Sean, yes is my domain. I was not aware of the Clojars verification. I will look into that. Thank you!

Joshua Suskalo21:02:55

clojars verification obviously also does not mess with your namespace names.

Joshua Suskalo21:02:21

Personally I go the route of making a unique name, googling the name with clojure, and then publishing with project.core for single-ns projects, and project.module for every module in a multi-ns project. This works out fine in a lot of communities, I haven't seen issues in practice with it in the clojure community. The main time you see different toplevel nses with the same name is in forks, and it would be rare that you would want to forks of the same project in your project dependencies at once.


I'm toying with the idea of making a REPL that supports picking up the current ns for both read and eval from an atom so that I can set the ns out of band. Is this a dumb approach?


It certainly seems a bit hacky, but 🤷 .