This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-07-27
Channels
- # announcements (3)
- # babashka (16)
- # beginners (177)
- # calva (102)
- # cider (2)
- # clj-kondo (12)
- # clojars (10)
- # clojure (91)
- # clojure-argentina (3)
- # clojure-australia (5)
- # clojure-europe (16)
- # clojure-nl (1)
- # clojure-uk (10)
- # clojurescript (73)
- # community-development (8)
- # cursive (9)
- # depstar (7)
- # fulcro (5)
- # helix (1)
- # introduce-yourself (1)
- # jobs-discuss (18)
- # lsp (32)
- # luminus (1)
- # malli (2)
- # music (4)
- # off-topic (20)
- # pathom (19)
- # polylith (15)
- # re-frame (4)
- # reagent (6)
- # ring (13)
- # sci (36)
- # shadow-cljs (7)
- # spacemacs (4)
- # sql (3)
- # tools-deps (112)
- # vim (21)
in clojurescript I can use the analyzer that comes with it at macro time to statically detect things like local bindings that are used in a body passed to the macro. is there an easy way to get that sort of local context in JVM clojure?
I am very fond of this macro
(ins)user=> (defmacro locals [] (into {} (map (juxt (comp keyword name) identity)) (keys &env)))
#'user/locals
(cmd)user=> (let [a 0 b 1] ((fn [x y] (locals)) "fruit" "albatross"))
{:a 0, :b 1, :x "fruit", :y "albatross"}
move the creation of the fn and the let bindings are no longer visible
ins)user=> (defn show-locals [x y] (locals))
#'user/show-locals
(ins)user=> (let [a 0 b 1] (show-locals "fruit" "albatross"))
{:x "fruit", :y "albatross"}
@U4YGF4NGM if it's not in &env, then it should resolve
otherwise 💥
Hi I have been having a problem with configuring the clojure project. Anyone who help me would be appreciated. Thanks!
Sounds like you would find best help in #beginners A preliminary description over there would help. Good luck with your project! :)
can someone tell me what is the correct way to write the defmulti
for the following defmethod
(defmethod rte/match :pattern
[pattern items & {:keys [promise-disjoint
hot-spot]}]
(rte/match (rte/compile pattern) items :promise-disjoint true :hot-spot hot-spot))
Here is what I have, but I'm not sure what to do with the &key
specification in the defmulti
.
(defmulti rte/match
"(rte/match rte sequence :promise-disjoint true|false)
Given an rte pattern or finite automaton generated by rte-to-dfa (or rte/compile),
determine whether the given sequence, items, matches the regular type expression.
If the caller wishes to check more than one sequence against the same
pattern, it is probably better to call rte/compile, to get an automaton, and
use that same automaton in several calls to rte/match to avoid
multiple conversions/look-ups, as the correspondence of pattern
to compiled Dfa is maintained via the memoize function."
(fn [rte _items & {:keys [promise-disjoint
hot-spot]}]
(dispatch rte 'rte/match)))
The problem is that promise-disjoint
and hot-spot
are unused in the (fn...)
& {:as _}
is that really the good way? It doesn't indicate to the caller what the valid/indented/supported keyword arguments are.
It depends why you're doing it. Since you said "The problem is that promise-disjoint and hot-spot are unused in the (fn...)" I thought you didn't want the names bound and unused.
it is just the clj-kondo complains that the variables are unused, and I cannot rename them to start with _ because that'll change the semantics. I didn't want to compile to the clj-kondo maintainers if there was a clojure-esque way to handle it.
{_promise-disjoint :promise-disjoint _hot-spot :hot-spot}
should work then.
ahhhh. good suggestion!!
That form of destructuring allows you to name the bound vars whatever you want and kondo should ignore them because of the leading _
unfortunately it appears clj-kondo still complains, but that seems like a bug in cli-kondo. maybe there's already an issue about that. I'll check
It looks like defmulti
allows an attr-map so I you could use :arglists
metadata there to declare readable help for users and then still use & {:as _}
for the actual arglist?
dev=> (defmulti example "docstring" {:arglists '([foo bar & {:keys [quux]}])} (fn [x _ & {:as _}] x))
#'dev/example
dev=> (doc example)
-------------------------
dev/example
([foo bar & {:keys [quux]}])
docstring
{_promise-disjoint :promise-disjoint _hot-spot :hot-spot}
is that the correct order, or should it be {:promise-disjoint _disjoint, :hot-spot _hot-spot}
? just want to make sure before I complain any further.
I'd use the :arglists
approach 🙂
Hey Sean, do you have an idea what is spec trying to tell me here?
(defmulti rte/match
"(rte/match rte sequence :promise-disjoint true|false)
Given an rte pattern or finite automaton generated by rte-to-dfa (or rte/compile),
determine whether the given sequence, items, matches the regular type expression.
If the caller wishes to check more than one sequence against the same
pattern, it is probably better to call rte/compile, to get an automaton, and
use that same automaton in several calls to rte/match to avoid
multiple conversions/look-ups, as the correspondence of pattern
to compiled Dfa is maintained via the memoize function."
(fn [rte _items & {:keys {_promise-disjoint :promise-disjoint
_hot-spot :hot-spot}}]
(dispatch rte 'rte/match)))
here is the spec message.
Show: Project-Only All
Hide: Clojure Java REPL Tooling Duplicates (45 frames hidden)
2. Unhandled clojure.lang.Compiler$CompilerException
Error compiling src/clojure_rte/rte_construct.clj at (2056:3)
#:clojure.error{:phase :macro-syntax-check,
:line 2056,
:column 3,
:source
"/Users/jnewton/Repos/clojure-rte/src/clojure_rte/rte_construct.clj",
:symbol clojure.core/fn}
Compiler.java: 6971 clojure.lang.Compiler/checkSpecs
Compiler.java: 6987 clojure.lang.Compiler/macroexpand1
core.clj: 3214 clojure.core/eval
core.clj: 3210 clojure.core/eval
interruptible_eval.clj: 87 nrepl.middleware.interruptible-eval/evaluate/fn/fn
AFn.java: 152 clojure.lang.AFn/applyToHelper
AFn.java: 144 clojure.lang.AFn/applyTo
core.clj: 665 clojure.core/apply
core.clj: 1973 clojure.core/with-bindings*
...
Thread.java: 834 java.lang.Thread/run
1. Caused by clojure.lang.ExceptionInfo
Call to clojure.core/fn did not conform to spec.
#:clojure.spec.alpha{:problems
({:path
[:fn-tail
:arity-1
:params
:var-params
:var-form
:local-symbol],
:pred clojure.core/simple-symbol?,
:val
{:keys
{_promise-disjoint :promise-disjoint,
_hot-spot :hot-spot}},
:via
[:clojure.core.specs.alpha/params+body
:clojure.core.specs.alpha/param-list
:clojure.core.specs.alpha/param-list
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/local-name],
:in [0 3]}
{:path
[:fn-tail
:arity-1
:params
:var-params
:var-form
:seq-destructure],
:pred clojure.core/vector?,
:val
{:keys
{_promise-disjoint :promise-disjoint,
_hot-spot :hot-spot}},
:via
[:clojure.core.specs.alpha/params+body
:clojure.core.specs.alpha/param-list
:clojure.core.specs.alpha/param-list
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/seq-binding-form],
:in [0 3]}
{:path
[:fn-tail
:arity-1
:params
:var-params
:var-form
:map-destructure
:keys],
:pred clojure.core/vector?,
:val
{_promise-disjoint :promise-disjoint,
_hot-spot :hot-spot},
:via
[:clojure.core.specs.alpha/params+body
:clojure.core.specs.alpha/param-list
:clojure.core.specs.alpha/param-list
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/binding-form
:clojure.core.specs.alpha/map-binding-form
:clojure.core.specs.alpha/map-special-binding
:clojure.core.specs.alpha/keys],
:in [0 3 :keys]}
{:path [:fn-tail :arity-n :params],
:pred clojure.core/vector?,
:val rte,
:via
[:clojure.core.specs.alpha/params+body
:clojure.core.specs.alpha/params+body
:clojure.core.specs.alpha/params+body
:clojure.core.specs.alpha/param-list
:clojure.core.specs.alpha/param-list],
:in [0 0]}),
:spec
#object[clojure.spec.alpha$regex_spec_impl$reify__2509 0x2bea9778 "clojure.spec.alpha$regex_spec_impl$reify__2509@2bea9778"],
:value
([rte
_items
&
{:keys
{_promise-disjoint :promise-disjoint,
_hot-spot :hot-spot}}]
(dispatch rte 'rte/match)),
:args
([rte
_items
&
{:keys
{_promise-disjoint :promise-disjoint,
_hot-spot :hot-spot}}]
(dispatch rte 'rte/match))}
alpha.clj: 705 clojure.spec.alpha/macroexpand-check
alpha.clj: 697 clojure.spec.alpha/macroexpand-check
AFn.java: 156 clojure.lang.AFn/applyToHelper
AFn.java: 144 clojure.lang.AFn/applyTo
Var.java: 705 clojure.lang.Var/applyTo
Compiler.java: 6969 clojure.lang.Compiler/checkSpecs
Compiler.java: 6987 clojure.lang.Compiler/macroexpand1
Compiler.java: 7092 clojure.lang.Compiler/analyzeSeq
Compiler.java: 6789 clojure.lang.Compiler/analyze
Compiler.java: 6745 clojure.lang.Compiler/analyze
Compiler.java: 2666 clojure.lang.Compiler$NewExpr$Parser/parse
Compiler.java: 7106 clojure.lang.Compiler/analyzeSeq
Compiler.java: 6789 clojure.lang.Compiler/analyze
Compiler.java: 38 clojure.lang.Compiler/access$300
Compiler.java: 596 clojure.lang.Compiler$DefExpr$Parser/parse
Compiler.java: 7106 clojure.lang.Compiler/analyzeSeq
Compiler.java: 6789 clojure.lang.Compiler/analyze
Compiler.java: 6745 clojure.lang.Compiler/analyze
Compiler.java: 6120 clojure.lang.Compiler$BodyExpr$Parser/parse
Compiler.java: 7106 clojure.lang.Compiler/analyzeSeq
Compiler.java: 6789 clojure.lang.Compiler/analyze
Compiler.java: 6745 clojure.lang.Compiler/analyze
Compiler.java: 2837 clojure.lang.Compiler$IfExpr$Parser/parse
Compiler.java: 7106 clojure.lang.Compiler/analyzeSeq
Compiler.java: 6789 clojure.lang.Compiler/analyze
Compiler.java: 7094 clojure.lang.Compiler/analyzeSeq
Compiler.java: 6789 clojure.lang.Compiler/analyze
Compiler.java: 6745 clojure.lang.Compiler/analyze
Compiler.java: 6120 clojure.lang.Compiler$BodyExpr$Parser/parse
Compiler.java: 6436 clojure.lang.Compiler$LetExpr$Parser/parse
Compiler.java: 7106 clojure.lang.Compiler/analyzeSeq
Compiler.java: 6789 clojure.lang.Compiler/analyze
Compiler.java: 6745 clojure.lang.Compiler/analyze
Compiler.java: 6120 clojure.lang.Compiler$BodyExpr$Parser/parse
Compiler.java: 5467 clojure.lang.Compiler$FnMethod/parse
Compiler.java: 4029 clojure.lang.Compiler$FnExpr/parse
Compiler.java: 7104 clojure.lang.Compiler/analyzeSeq
Compiler.java: 6789 clojure.lang.Compiler/analyze
Compiler.java: 7173 clojure.lang.Compiler/eval
Compiler.java: 7131 clojure.lang.Compiler/eval
core.clj: 3214 clojure.core/eval
core.clj: 3210 clojure.core/eval
interruptible_eval.clj: 87 nrepl.middleware.interruptible-eval/evaluate/fn/fn
AFn.java: 152 clojure.lang.AFn/applyToHelper
AFn.java: 144 clojure.lang.AFn/applyTo
core.clj: 665 clojure.core/apply
core.clj: 1973 clojure.core/with-bindings*
core.clj: 1973 clojure.core/with-bindings*
RestFn.java: 425 clojure.lang.RestFn/invoke
interruptible_eval.clj: 87 nrepl.middleware.interruptible-eval/evaluate/fn
main.clj: 414 clojure.main/repl/read-eval-print/fn
main.clj: 414 clojure.main/repl/read-eval-print
main.clj: 435 clojure.main/repl/fn
main.clj: 435 clojure.main/repl
main.clj: 345 clojure.main/repl
RestFn.java: 1523 clojure.lang.RestFn/invoke
interruptible_eval.clj: 84 nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 56 nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 152 nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
AFn.java: 22 clojure.lang.AFn/run
session.clj: 202 nrepl.middleware.session/session-exec/main-loop/fn
session.clj: 201 nrepl.middleware.session/session-exec/main-loop
AFn.java: 22 clojure.lang.AFn/run
Thread.java: 834 java.lang.Thread/run
:keys
expects a vector, not a hash map. You want
{_promise-disjoint :promise-disjoint _hot-spot :hot-spot}
not
{:keys {_promise-disjoint :promise-disjoint
_hot-spot :hot-spot}}
so where does the :or {a 100 b 200}
go and the :as all-args
?
I see, it goes right there in the same {...}
not what I'd have guessed
and If I want promise-disjoint
to be unused, but hot-spot
to be used. I cannot use the [...]
form, apparently I have to use the {_promise-disjoint :promise-disjoint, hot-spot :hot-spot}
form.
Yeah, it's enough of a strange syntax that I pretty much never use that style of destructuring. Sometimes I'll use it in a let
where I really do need renaming but that's about it.
Pretty sure you can combine (re)named bindings with :keys
and :or
and :as
all in one hash map. I know you can also combine :keys
and :foo/keys
when you want to bind to :foo/bar
as well as :quux
for example.
I pretty much always have to look up how the renaming destructuring works!
yes probably, but it seems the same problem exists in clj-kondo even with fn
s, not really related to defmulti
.
Do all values that return true for fn?
also return true for ifn?
. I guess that means do all objects that implement clojure.lang.Fn
also implement clojure.lang.IFn
? How do I infer this piece of information from Clojure's source?
I guess it might be worth adding it as a note https://clojuredocs.org/clojure.core/ifn_q whether all things that return true for fn?
also return true for ifn?
.
Fn
is just a marker interface: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Fn.java
IFn
is where all the invoke
stuff is https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IFn.java
I don't know if everything that implements Fn
also implements IFn
...
AFn
implements IFn
and AFunction
extends AFn
and implements Fn
-- and that seems to be the only thing that implements Fn
so, yeah, everything that satisfies fn?
will also happen to satisfy ifn?
.
Does that help @UMPJRJU9E?
The marker interface Fn
is useful for determining if you have an actual function in hand rather than something that acts like a function.
Does anyone have any experience using clj-async-profiler (https://github.com/clojure-goes-fast/clj-async-profiler) w/ OpenJDK 8?
I get an error:
Could not find libjvm among loaded libraries. Unsupported JVM?
so I’m concerned I need to switch over to Oracle JDK.Certainly appears like openjdk 8 should be supported, by the underlying lib anyway. A brief perusal through the source suggests that this error could happen if their agent binary isn't attached to the jvm. But that's barely-educated speculation.
Here's some advice regarding JDK: https://github.com/jvm-profiling-tools/async-profiler/issues/407 So maybe try Zulu OpenJDK? In either case, I would advice you to file an issue here - you will likely get a response from Andrei soon.
I’m on OS X, using (now) Oracle JDK 16.0.2 (I was originally on OpenJDK 8 at the start of this process).
At least part of the problem is that I did not have the environment variable JAVA_HOME
set. New error message is can not attach to current VM
which is better.
I will add more info in thread to not spam the channel.
The issue is about wild string to paste into test which throw
Unsupported escape character: \
or is not =
(is
(= (.format json-payload/formatter
(doto (message->LogRecord "foo")
(.setThrown (Exception. "bar"))))
"")
"exception")
(.format json-payload/formatter
(doto (message->LogRecord "foo")
(.setThrown (Exception. "bar"))))
=>
"{\"severity\":\"INFO\",\"logger-name\":\"ns\",\"message\":\"java.lang.Exception: bar\
\\tat logs_helpers.google.json_payload_test$eval3010.invokeStatic(json_payload_test.clj:2)\
\\tat logs_helpers.google.json_payload_test$eval3010.invoke(json_payload_test.clj:23)\
\\tat clojure.lang.Compiler.eval(Compiler.java:7181)\
\\tat clojure.lang.Compiler.eval(Compiler.java:7136)\
\\tat clojure.core$eval.invokeStatic(core.clj:3202)\
\\tat clojure.core$eval.invoke(core.clj:3198)\
\\tat nrepl.middleware.interruptible_eval$evaluate$fn__939.invoke(interruptible_eval.clj:91)\
\\tat clojure.main$repl$read_eval_print__9110$fn__9113.invoke(main.clj:437)\
\\tat clojure.main$repl$read_eval_print__9110.invoke(main.clj:437)\
\\tat clojure.main$repl$fn__9119.invoke(main.clj:458)\
\\tat clojure.main$repl.invokeStatic(main.clj:458)\
\\tat clojure.main$repl.doInvoke(main.clj:368)\
\\tat clojure.lang.RestFn.invoke(RestFn.java:1523)\
\\tat nrepl.middleware.interruptible_eval$evaluate.invokeStatic(interruptible_eval.clj:84)\
\\tat nrepl.middleware.interruptible_eval$evaluate.invoke(interruptible_eval.clj:56)\
\\tat nrepl.middleware.interruptible_eval$interruptible_eval$fn__965$fn__969.invoke(interruptible_eval.clj:155)\
\\tat clojure.lang.AFn.run(AFn.java:22)\
\\tat nrepl.middleware.session$session_exec$main_loop__1067$fn__1071.invoke(session.clj:190)\
\\tat nrepl.middleware.session$session_exec$main_loop__1067.invoke(session.clj:189)\
\\tat clojure.lang.AFn.run(AFn.java:22)\
\\tat java.base/java.lang.Thread.run(Thread.java:834)\
\",\"logger-message\":\"foo\"}
"
If I will try to do
(print (.format json-payload/formatter
(doto (message->LogRecord "foo")
(.setThrown (Exception. "bar")))))
and use this string for test, then it is not =
This string is produced by
(if thrown
(let [w (StringWriter.)]
(.printStackTrace thrown (PrintWriter. w))
(.toString w))
(.getMessage record))
if it mattersI am trying with all kinds of
(spit "foo.edn" (pr-str (.format json-payload/formatter
(doto (message->LogRecord "foo")
(.setThrown (Exception. "bar"))))))
with the same effectWhat if you slurp
what you have spit
before, instead of hard-coding the string in your code?
oh I think I found a true issue…. In exception there is eval3180
which can have different number…
Turned out this wasn't a bug, the code was just incorrect https://clojurians.slack.com/archives/C03S1KBA2/p1627405393446200 :)
I remember seeing an old project which basically had an alternate clojure.core, it was meant that you'd exclude clojure.core and use their standard lib instead. Does anyone know what I'm talking about? I'm trying to find it again. The big difference was that it broke down clojure.core in many smaller Namespaces
Haha, well yours is superior to mine, as I had failed to find it with my own google-fu
i'm trying to use emit some html with a style attribute background-color rgb()
. hiccup is seemingly trying to prevent some dangerous html but i don't want sanitization in this case. Does anyone know a workaround?
(hiccup.core/html
[:span {:style {:background-color "rgb(239, 140, 140)"}}
"hi"])
"<span style=\"{:background-color "rgb(239, 140, 140)"}\">hi</span>"
It may work with hiccup2.core, I see this in the https://github.com/weavejester/hiccup/blob/master/CHANGELOG.md#200-alpha1-2017-01-15: "Added new syntax for class and style attributes"
I really like how macroexpand(-all) helps to understand and visualize a macro. I don’t think anything similar exists for functions, as in a stepwise substitution of the evaluations. That would be very useful. How crazy would it be to be to try to implement that?
@dpsutton I think reagent also has a way to emit html - yea this thing: http://reagent-project.github.io/docs/master/reagent.dom.server.html#var-render-to-string
Maybe this one? https://github.com/tonsky/rum/blob/gh-pages/src/rum/server_render.clj#L454
This looks like it is the PR that added it btw: https://github.com/weavejester/hiccup/pull/139