This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-03-03
Channels
- # announcements (3)
- # babashka (29)
- # beginners (95)
- # calva (109)
- # cider (16)
- # clj-kondo (6)
- # cljdoc (2)
- # cljsrn (2)
- # cljtogether (1)
- # clojure (85)
- # clojure-europe (26)
- # clojure-india (1)
- # clojure-seattle (1)
- # clojure-uk (6)
- # clojurescript (14)
- # conjure (4)
- # cursive (8)
- # datomic (6)
- # emacs (21)
- # events (1)
- # figwheel-main (5)
- # fulcro (11)
- # graalvm (32)
- # graphql (1)
- # holy-lambda (7)
- # humbleui (7)
- # jobs (3)
- # membrane (8)
- # nextjournal (31)
- # off-topic (29)
- # pathom (14)
- # polylith (6)
- # portal (16)
- # practicalli (4)
- # reitit (17)
- # releases (1)
- # remote-jobs (2)
- # ring (4)
- # sci (20)
- # shadow-cljs (24)
- # sql (1)
- # vim (12)
- # xtdb (3)
https://clojurians.slack.com/archives/C053AK3F9/p1646260287510409 That sounds a lot like EDN to me.
I am stuck figuring out how to create a list with elements from 2 long object ? argh> (def bob 3) #'argh/bob argh> (def sue 7) #'argh/sue argh> (def l1 '(7 3)) #'argh/l1 argh> l1 (7 3) argh> (def l1-from-bob-n-sue '(bob sue)) #'argh/l1-from-bob-n-sue argh> l1-from-bob-n-sue (bob sue) But i want same as l1 ie.. (7 3)
Use (list bob sue)
The problem is that you use quote: '(bob sue)
does not evaluate bob
and sue
but just keeps them as symbols.
The list
function evaluates its arguments and puts them in a list.
Alternatively you could use âsyntax quoteâ with âunquoteâ:
(def l1-from-bob-n-sue `(~bob ~sue))
Here, the backtick is a special form of quoting allowing to selectively âunquoteâ using the tilde ~
. But list
is probably easier to read đYeah the unquote thingy was the missing thing in my idea but def list was the intent
Why vector isnt that just another form of memory layout ? How does vector makes it easier?
Vectors do not require quoting, i.e. you can just write (def l1-from-bob-n-sue [bob sue])
and yes vectors grow (`conj`) at the end whereas lists grow at the beginning. Using vectors is idiomatic and common in clojure.
You can pretty much always use vector [bob sue]
. If you are really thinking how to optimise your performance, list has O(n) random access look up time compared to O(1) in vector.
I think quotes are from the lisp heritage and perhaps not the first thing you should consider learning
Yes @UTA54EFQF, the internals are different between vector and list but even though lists definitely have their uses, most of the time, especially as a beginner, when you think you need a list you really want a vector in Clojure, so reach out for vectors first.
(comment
(def l (list :a :b :c))
(def v [:a :b :c])
(get v 1) ;; => :b
(get l 1) ;; => nil
(conj v :d) ;; => [:a :b :c :d]
(conj l :d) ;; => (:d :a :b :c)
(assoc v 1 :new-b) ;; => [:a :new-b :c]
(assoc l 1 :new-b) ;; => ClassCastException
)
(plus the whole O(1) vs O(n) random access)does anyone know what might be causing this error when Iâm making a request to the server:
{:cached nil, :request-time 35, :repeatable? false, :protocol-version {:name "HTTP", :major 1, :minor 1}, :streaming? true, :http-client #object[org.apache.http.impl.client.InternalHttpClient 0xb6a995b "[email protected]"], :chunked? false, :type :clj-http.client/unexceptional-status, :reason-phrase "Server Error", :headers {"Connection" "close", "Cache-Control" "must-revalidate,no-cache,no-store", "Content-Type" "text/html;charset=iso-8859-1", "Content-Length" "3076", "Server" "Jetty(9.4.28.v20200408)"}, :orig-content-encoding nil, :status 500, :length 3076, :body "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"/>\n<title>Error 500 java.lang.IllegalArgumentException: No implementation of method: :write-body-to-stream of protocol: #'ring.core.protocols/StreamableResponseBody found for class: clojure.lang.PersistentArrayMap</title>\n</head>\n<body><h2>HTTP ERROR 500 java.lang.IllegalArgumentException: No implementation of method: :write-body-to-stream of protocol: #'ring.core.protocols/StreamableResponseBody found for class: clojure.lang.PersistentArrayMap</h2>\n<table>\n<tr><th>URI:</th><td>/api/login</td></tr>\n<tr><th>STATUS:</th><td>500</td></tr>\n<tr><th>MESSAGE:</th><td>java.lang.IllegalArgumentException: No implementation of method: :write-body-to-stream of protocol: #'ring.core.protocols/StreamableResponseBody found for class: clojure.lang.PersistentArrayMap</td></tr>\n<tr><th>SERVLET:</th><td>-</td></tr>\n<tr><th>CAUSED BY:</th><td>java.lang.IllegalArgumentException: No implementation of method: :write-body-to-stream of protocol: #'ring.core.protocols/StreamableResponseBody found for class: clojure.lang.PersistentArrayMap</td></tr>\n</table>\n<h3>Caused by:</h3><pre>java.lang.IllegalArgumentException: No implementation of method: :write-body-to-stream of protocol: #'ring.core.protocols/StreamableResponseBody found for class: clojure.lang.PersistentArrayMap\n\tat clojure.core$_cache_protocol_fn.invokeStatic(core_deftype.clj:583)\n\tat clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:575)\n\tat ring.core.protocols$eval25675$fn__25676$G__25666__25685.invoke(protocols.clj:8)\n\tat ring.util.servlet$update_servlet_response.invokeStatic(servlet.clj:106)\n\tat ring.util.servlet$update_servlet_response.invoke(servlet.clj:91)\n\tat ring.util.servlet$update_servlet_response.invokeStatic(servlet.clj:95)\n\tat ring.util.servlet$update_servlet_response.invoke(servlet.clj:91)\n\tat ring.adapter.jetty$proxy_handler$fn__32745.invoke(jetty.clj:28)\n\tat ring.adapter.jetty.proxy$org.eclipse.jetty.server.handler.AbstractHandler$ff19274a.handle(Unknown Source)\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)\n\tat org.eclipse.jetty.server.Server.handle(Server.java:500)\n\tat org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:383)\n\tat org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:547)\n\tat org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:375)\n\tat org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:273)\n\tat org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)\n\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)\n\tat org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:806)\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:938)\n\tat java.base/java.lang.Thread.run(Thread.java:833)\n</pre>\n<hr><a href=\"\">Powered by Jetty:// 9.4.28.v20200408</a><hr/>\n\n</body>\n</html>\n", :trace-redirects []}
The error is
> java.lang.IllegalArgumentException: No implementation of method: :write-body-to-stream of protocol: ring.core.protocols/StreamableResponseBody
found for class: clojure.lang.PersistentArrayMap
Seems straightforward. You returned a map from a handler and your app doesnât know how to serialize that to the response. I am guessing you intended that to come back as json or edn but havenât hooked up the middleware that would do that transformation?
Hello, can I have the accepted way to go from {:a []}
to {:a [:b]}
? in particular when using update-in?
Is it just (update-in {:a []} [:a] cons :b)
user=> (conj [1 2 3] 4)
[1 2 3 4]
user=> (cons [1 2 3] 4) ;; broken arg order!
Execution error (IllegalArgumentException) at user/eval3 (REPL:1).
Don't know how to create ISeq from: java.lang.Long
user=> (cons 4 [1 2 3])
(4 1 2 3) ;; note it returns a seq, not a vector!
yeah but isnât it (conj coll item)
where the funciton here will be getting coll in the last position?
update-in and similar functions will apply the function you pass (conj) to the thing it found, followed by trailing args
âfollowed by trailing argsâ ok I see
I did not grok this point about the behavior of update-in
i can add more rtailing args but the second position of whatâs gonna get executed will be the []
(in this case)
there are a few other functions in clojure.core with this same exact argument shape: update-in update swap!
As a beginner, I think the docstring for update-in
is unnecessarily subtle as to this point!
I would recommend checking the community-written http://ClojureDocs.org on update-in
to see if it clarifies anything for you. It is not "official" docs, but there are often helpful examples there that the core documentation does not have.
You can create an http://ask.clojure.org question asking whether the built-in doc strings can be enhanced, but there is a very high bar there to pass before the Clojure core team would agree to changes.
Thanks @ghadi
does anyone know how one can replicate a request that contains :body-params using clj-http or peridot that donât support the :body-params keys but in which the params have to be sent in the body? Here are body-params being sent: https://github.com/metosin/reitit/blob/acfc48faa180e7e194667425147bb9f9e870dc8c/examples/ring-spec-swagger/test/example/server_test.clj#L20. But when I try to send body-params like so using peridot:
(-> session
(request "/api/reset-password"
:content-type "application/json"
:request-method :post
:body (cc/generate-string
{:email email
:newPassword newPassword
:resetToken token}
)))
the body-params donât seem to be detected in the server. What am I doing wrong?the set of middleware will tell you how and where the :body-params key comes from, which will tell you how it needs t o be sent
weâre using the same middleware as in the github example:
[;; swagger feature
swagger/swagger-feature
;; query-params & form-params
parameters/parameters-middleware
;; content-negotiation
muuntaja/format-negotiate-middleware
;; encoding response body
muuntaja/format-response-middleware
;; exception handling
exception/exception-middleware
;; decoding request body
muuntaja/format-request-middleware
;; coercing response bodys
coercion/coerce-response-middleware
;; coercing request parameters
coercion/coerce-request-middleware
;; multipart
multipart/multipart-middleware]
but they seems to get the body-params in the server, whereas we donâtI dunno anything about all this metosi stuff, but you have format-response-middleware and don't appear to have similar for requests
@hiredman I have both muuntaja/format-request-middleware and muuntaja/format-response-middleware
then you need to look at request middleware, figure out its rules for decoding stuff (good luck) and then have your requests put things in the format it wants
technically all objects are passed by reference on the JVM (apart from primitive values like longs and doubles)
I need to pass a map to a function and need to add new key-value pair in that map and then use that map back in the calling function.
All Clojure collections are immutable. The typical way to do what you ask for is to pass one collection as a parameter, and the function returns a new collection that is similar to the one passed in, but with whatever "changes" you want to return, in the return value.
This is a big shift in thinking in day-to-day application development if you are accustomed to mutating objects.
In Clojure on the JVM, you can of course use mutable Java collections if you want to.
And in ClojureScript, you can use mutable JavaScript collections.
The thing is that it is already returning a function and I can not return new collection so I need to find way of extracting that value somehow
I think this might fix it: [ring.middleware.format-params :refer [wrap-format-params]] but including this gives:
Could not locate ring/middleware/format_params__init.class, ring/middleware/format_params.clj or ring/middleware/format_params.cljc on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.
even though I have ring in my project.clj
it doesn't exist here https://github.com/ring-clojure/ring/tree/master/ring-core/src/ring/middleware
I get this:
actual: java.lang.NullPointerException: Cannot invoke "clojure.lang.IFn.invoke(Object, Object, Object)" because "this.handle_error" is null
at ring.middleware.format_params$wrap_format_params$fn__28345.invoke (format_params.clj:115)
reitit.ring$ring_handler$fn__23796.invoke (ring.cljc:329)
clojure.lang.AFn.applyToHelper (AFn.java:154)
clojure.lang.AFn.applyTo (AFn.java:144)
clojure.lang.AFunction$1.doInvoke (AFunction.java:31)
clojure.lang.RestFn.invoke (RestFn.java:408)
peridot.core$request.invokeStatic (core.clj:18)
peridot.core$request.doInvoke (core.clj:12)
clojure.lang.RestFn.invoke (RestFn.java:521)
helpers.helpers$register_user.invokeStatic (helpers.clj:145)
helpers.helpers$register_user.invoke (helpers.clj:143)
unit.login_test$fn__33611.invokeStatic (login_test.clj:12)
unit.login_test/fn (login_test.clj:11)
clojure.test$test_var$fn__9761.invoke (test.clj:717)
clojure.test$test_var.invokeStatic (test.clj:717)
clojure.test$test_var.invoke (test.clj:708)
clojure.test$test_vars$fn__9787$fn__9792.invoke (test.clj:735)
helpers.fixtures$with_db$fn__33049.invoke (fixtures.clj:82)
clojure.core$with_redefs_fn.invokeStatic (core.clj:7516)
clojure.core$with_redefs_fn.invoke (core.clj:7500)
helpers.fixtures$with_db.invokeStatic (fixtures.clj:29)
helpers.fixtures$with_db.invoke (fixtures.clj:23)
clojure.test$compose_fixtures$fn__9755$fn__9756.invoke (test.clj:694)
clojure.test$default_fixture.invokeStatic (test.clj:687)
clojure.test$default_fixture.invoke (test.clj:683)
clojure.test$compose_fixtures$fn__9755.invoke (test.clj:694)
clojure.test$test_vars$fn__9787.invoke (test.clj:735)
clojure.test$default_fixture.invokeStatic (test.clj:687)
clojure.test$default_fixture.invoke (test.clj:683)
clojure.test$test_vars.invokeStatic (test.clj:731)
clojure.test$test_all_vars.invokeStatic (test.clj:737)
clojure.test$test_ns.invokeStatic (test.clj:758)
clojure.test$test_ns.invoke (test.clj:743)
clojure.core$map$fn__5884.invoke (core.clj:2759)
clojure.lang.LazySeq.sval (LazySeq.java:42)
clojure.lang.LazySeq.seq (LazySeq.java:51)
clojure.lang.Cons.next (Cons.java:39)
clojure.lang.RT.boundedLength (RT.java:1793)
clojure.lang.RestFn.applyTo (RestFn.java:130)
clojure.core$apply.invokeStatic (core.clj:669)
clojure.test$run_tests.invokeStatic (test.clj:768)
clojure.test$run_tests.doInvoke (test.clj:768)
clojure.lang.RestFn.invoke (RestFn.java:408)
clojure.test$run_tests.invokeStatic (test.clj:773)
clojure.test$run_tests.invoke (test.clj:768)
unit.login_test$eval33664.invokeStatic (login_test.clj:50)
unit.login_test$eval33664.invoke (login_test.clj:50)
clojure.lang.Compiler.eval (Compiler.java:7181)
clojure.lang.Compiler.load (Compiler.java:7640)
user$eval33597.invokeStatic (form-init15147153642663810079.clj:1)
user$eval33597.invoke (form-init15147153642663810079.clj:1)
clojure.lang.Compiler.eval (Compiler.java:7181)
clojure.lang.Compiler.eval (Compiler.java:7136)
clojure.core$eval.invokeStatic (core.clj:3202)
clojure.core$eval.invoke (core.clj:3198)
nrepl.middleware.interruptible_eval$evaluate$fn__31851$fn__31852.invoke (interruptible_eval.clj:87)
clojure.lang.AFn.applyToHelper (AFn.java:152)
clojure.lang.AFn.applyTo (AFn.java:144)
clojure.core$apply.invokeStatic (core.clj:667)
clojure.core$with_bindings_STAR_.invokeStatic (core.clj:1977)
clojure.core$with_bindings_STAR_.doInvoke (core.clj:1977)
clojure.lang.RestFn.invoke (RestFn.java:425)
nrepl.middleware.interruptible_eval$evaluate$fn__31851.invoke (interruptible_eval.clj:87)
clojure.main$repl$read_eval_print__9110$fn__9113.invoke (main.clj:437)
clojure.main$repl$read_eval_print__9110.invoke (main.clj:437)
clojure.main$repl$fn__9119.invoke (main.clj:458)
clojure.main$repl.invokeStatic (main.clj:458)
clojure.main$repl.doInvoke (main.clj:368)
clojure.lang.RestFn.invoke (RestFn.java:1523)
nrepl.middleware.interruptible_eval$evaluate.invokeStatic (interruptible_eval.clj:84)
nrepl.middleware.interruptible_eval$evaluate.invoke (interruptible_eval.clj:56)
nrepl.middleware.interruptible_eval$interruptible_eval$fn__31882$fn__31886.invoke (interruptible_eval.clj:152)
clojure.lang.AFn.run (AFn.java:22)
nrepl.middleware.session$session_exec$main_loop__31950$fn__31954.invoke (session.clj:202)
nrepl.middleware.session$session_exec$main_loop__31950.invoke (session.clj:201)
clojure.lang.AFn.run (AFn.java:22)
java.lang.Thread.run (Thread.java:833)
that looks like exception happening while looking for an error handle, which doesn't tell you what caused it to look for an error handler
oh, you aren't actually making a request, you are just passing the data to the function in a test, and passing a string where it wants an inputstream (would be my guess)
itâs a request
(-> session
(request "/api/reset-password"
:content-type "application/json"
:request-method :post
:body (cc/generate-string
{:email email
:newPassword newPassword
:resetToken token}
)))
itâs through https://github.com/xeqi/peridot
so the metosin whatever, if the body is present, treats it as an inputstream and tries to decode it
I mean, I don't know, if I were you the thing to do is figure out how to set whatever error handler retit wants so that you can display the error that happens, instead of getting a stacktrace that just tells you there was an error trying to call the error handler
it doesn't have a :body, it passes in :body-params, so the stuff doesn't look for an inputstream in :body to decode from
the exception only happens with wrap-format-parasm
without it I get:
{:spec
"(spec-tools.core/spec {:spec (clojure.spec.alpha/keys :req-un [:lms.auth.spec/resetToken :lms.auth.spec/newPassword :lms.auth.spec/email]), :type :map, :leaf? false})",
:problems
[{:path [],
:pred "clojure.core/map?",
:val nil,
:via [:lms.auth.spec/reset-password-params],
:in []}],
:type :reitit.coercion/request-coercion,
:coercion :spec,
:value nil,
:in [:request :body-params]}
notice :value nil in :request :body-params
thereâs gotta be a middleware that converts body to body-params
I tried wrap-format-params but that gave the exception