This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-02-23
Channels
- # announcements (2)
- # atom-editor (3)
- # babashka (49)
- # beginners (100)
- # biff (9)
- # calva (78)
- # clj-kondo (18)
- # clojure (143)
- # clojure-europe (13)
- # clojure-germany (1)
- # clojure-nl (2)
- # clojure-spec (5)
- # clojure-sweden (2)
- # clojure-uk (4)
- # clojurescript (58)
- # conjure (1)
- # cursive (4)
- # datascript (11)
- # datomic (63)
- # docker (7)
- # emacs (18)
- # events (1)
- # fulcro (18)
- # graalvm (5)
- # helix (4)
- # improve-getting-started (13)
- # jobs (4)
- # jobs-discuss (3)
- # lsp (15)
- # malli (90)
- # membrane (14)
- # off-topic (12)
- # other-languages (5)
- # pedestal (7)
- # polylith (53)
- # re-frame (15)
- # reitit (23)
- # releases (4)
- # remote-jobs (9)
- # ring (11)
- # shadow-cljs (90)
- # specter (2)
- # testing (3)
- # tools-build (63)
- # vim (2)
- # xtdb (8)
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 š
dev=> (type `(a b c))
clojure.lang.Cons
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]))
false
(because a LazySeq
is not a list either)
What question are you trying to ask?
dev=> (list? (range 3))
false
sequential?
perhaps? seqable?
maybe?
I have a definition like this
(def system
`(app
(db {:uri (config :db/uri)})
(dir-watcher-pool (config :dirs))))
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
But not a vector? sequential?
will be true
on a vector.
Several of those predicates test instance?
so you need to know what the underlying type hierarchy is.
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)
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
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
I think you can make them using keyword
but canāt read them (keyword "what/is/happening?");; => :what/is/happening?
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 access the namespace and name parts separately, but I guess nothing prevents you from having raw keywords with just dotted names
> 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.
it's ironic that that there are two concepts of namespaces, colliding in their name and usage
the dots in namespaces do have a mapping to file paths, but I otherwise I don't think they have any semantic
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?
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 https://replit.com/@eccentric-j/nbb-with-redefs-async#src/cli/core.cljs 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 https://github.com/funcool/promesa/pull/102 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 []
:clojure.spec.alpha/invalid)
workaround
(let []
(when true
:clojure.spec.alpha/invalid))
Bug?
on 1.10.3isn't this a case of a conformed value being equal to c.s.a/invalid when the let is validated causing it to fail
indeed
iirc you can do (def invalid :clojure.spec.alpha/invalid) and then refer to invalid
in your code
that works
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 https://aws.amazon.com/blogs/machine-learning/optimizing-application-performance-with-amazon-codeguru-profiler/ but I can't find if they use JFR behind the scenes or not.
They even have Clojure instructions: https://docs.aws.amazon.com/codeguru/latest/profiler-ug/clojure-language-support.html š
Seems to not have any compile time dependencies at all, so itās probably their own https://mvnrepository.com/artifact/software.amazon.awssdk/codeguruprofiler/2.17.134
If Codeguru aggregates it in a single place, it sounds like the nicer solution for AWS š
They might be using https://github.com/jvm-profiling-tools/async-profiler which is what the Clojure-goes-fast profiler uses.
You can generate a flame graph in production by embedding clj-async-profiler in your application. Pretty easy
Moreover, if you collect JVM metrics besides host metrics, check your heap and GC graphs
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?
Is this about right?
(let [foo (delay (some-other-func))]
(defn func []
(work-with @foo)))
it has the downside of requiring the result to be deref'ed but has the single execution semantics
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 boxingWhy 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.
Because ##NaN
is defined to not equal ##NaN
Where?
This means that an "optimization" is incorrect
Use ==
to compare numbers numerically
user=> (let [v ##NaN] (== v v))
false
user=> (let [f #(== % %)] (f ##NaN))
false
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)
true
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.
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 http://ask.clojure.org 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?
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)
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
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 https://gist.github.com/hiredman/1179073
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? š
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)
-------------------------
clojure.core/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
Spec
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.
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 https://guide.clojure.style/#namespace-declaration. 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
@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
com.stuartsierra.component
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@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.
Nothing prevents me from putting namespaces with others reverse dns though, right?
@U019RSW97UZ "I'm planning on usingĀ codes.stel/foobarbazĀ as the maven coordinates." -- I assume you own a https://stel.codes domain and can verify that for the Clojars team? See https://github.com/clojars/clojars-web/wiki/Verified-Group-Names
@U04V70XH6 Hey Sean, yes https://stel.codes is my domain. I was not aware of the Clojars verification. I will look into that. Thank you!
clojars verification obviously also does not mess with your namespace names.
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? https://gist.github.com/eerohele/45a255b249a2154431bfd70502cb625a