Hello, I'm creating an api with reitit with ring and using component approach, my main handler is a function in order to receive as param a component with all needed dependencies. I wanted to use ring.middleware.reload
to avoid having to restart my server at every change, but for what I could get from https://stackoverflow.com/a/43075132 I need to pass a var reference to wrap-reload
but I can't because I need to start the system, get all the components provided, and then call my handler with the component so it can have all the dependencies it needs. Do you have an idea how can I achieve that in this situation? Here is the project if you want to take a look: https://github.com/ashton/fiis-api
PS: sorry if it's kinda dumb question, started working with clojure recently
your system component comes from env?
Can you document all the pain points you have working with this library?
this seems like a pretty good example of the kind of lib clojure tends to have trouble with
and I am personally interested in what libraries can be written to ease some pains
Alright! Hope I can get a minimal example working ... ><
Any suggestions on how I should document it though? @emccue
As of now I've been trying to do a one to one translation of the code from java to clojure
I created a config component that could receive some env variables
like database credentials
What is the cost of turning a persistent collection into a transient and vice versa? Is this negligible, as in, it almost always pays off to use a transient if you have multiple edits, or should you make a careful trade-off?
user=> (defn assoc2 [m k1 v1 k2 v2] (-> m (assoc k1 v1) (assoc k2 v2)))
#'user/assoc2
user=> (time (dotimes [i 100000000] (assoc2 {} :a 1 :b 2)))
"Elapsed time: 4107.996251 msecs"
nil
user=> (defn assoc2transient [m k1 v1 k2 v2] (-> (transient m) (assoc! k1 v1) (assoc! k2 v2) persistent!))
#'user/assoc2transient
user=> (time (dotimes [i 100000000] (assoc2transient {} :a 1 :b 2)))
"Elapsed time: 7006.140274 msecs"
There's an inflection point at some size, I think around 8
Is there a reason behind not implementing this?
`{~@[:a 42]}
;; Syntax error, map literal must contain an even number of forms
The map literal is consumed during the reader stage.
The ~@
thing is expanded during the macro expansion stage, which is later.
persistent 0 59.834286 ns
transient 0 126.623222 ns
persistent 1 50.380727 ns
transient 1 97.708084 ns
persistent 2 77.446552 ns
transient 2 108.747859 ns
persistent 3 104.248826 ns
transient 3 121.066979 ns
persistent 4 129.282491 ns
transient 4 133.730972 ns
persistent 5 153.419134 ns
transient 5 149.018422 ns
persistent 6 180.185956 ns
transient 6 158.353261 ns
persistent 7 207.039484 ns
transient 7 170.311342 ns
persistent 8 234.054261 ns
transient 8 181.334001 ns
persistent 9 258.810761 ns
transient 9 194.844289 ns
persistent 10 286.604407 ns
transient 10 203.995842 ns
persistent 11 313.167452 ns
transient 11 217.507117 ns
persistent 12 340.265275 ns
transient 12 229.006417 ns
persistent 13 371.397952 ns
transient 13 242.451556 ns
persistent 14 395.458757 ns
transient 14 249.939500 ns
persistent 15 426.517073 ns
transient 15 264.421980 ns
(require '[criterium.core :as cc])
(doseq [n (range 16)]
(println "persistent " n)
(cc/quick-bench (reduce conj [] (range n)))
(println "transient " n)
(cc/quick-bench (persistent! (reduce conj! (transient []) (range n)))))
If you need it in a macro, you can just use hash-map
explicitly - there shouldn't be any noticeable difference.
Cool, this is with a vector. Can you run it with a map as well?
sure, please hold 🙂
looks like the inflection point for maps is around 4 elements
:thanks3:
welcome 🙂
Just to clarify, 4 assoc!
s are faster than the persistent version
this is not a complete test, however, it doesn't cover maps with more interesting shapes, I wonder if it has an effect
Some core fns switched to transients for performance, but considering the above benchmarks, the core fns should be actually slower after this change, for some inputs?
Which functions besides into?
But theoretically, yes
zipmap
Can someone tell me what this error is about?: I’m trying to handle a websocket connection using immutant async:
(def websocket-callbacks
"WebSocket callback functions"
{:on-open connect!
:on-close disconnect!
:on-message notify-clients!})
(defn ws-handler [request]
(async/as-channel request websocket-callbacks))
But calling the ws-handler gives :
No method in multimethod 'initialize-stream' for dispatch value: :servlet
on line
(async/as-channel request websocket-callbacks)
I'm beginning to see a small perf benefit when using over 10 keyvals but below that it's slower with transients, in a graalvm binary. I was trying to speed up the bindings in a loop, but more than 10 local loop bindings is pretty uncommon.
or hack it around using {~@[:a 42] ~@()}
😛
Idk what as-channel does but that error is telling you what you need to do: make a defmethod for initialize-stream for the value :servlet
How can I make lein-template clj-new compatible?
@karol.wojcik Why is it currently not compatible? I thought clj-new worked with lein templates out of the box but I might be mistaking
Hmm. Probably I don't know how to correctly call it with holy-lambda template :((
@karol.wojcik What have you tried?
@borkdude clj -X:new holy-lambda basic
you should write clj -X:new :template holy-lambda :something-else basic
, that is how -X
works, pass key/val (or path/val)
afaik you can still use the main function but this isn't documented by @seancorfield - I don't understand the tendency to move towards "EDN on the command line over well-design command line interface" but that's how it is
$ clojure -M:new -m clj-new.create holy-lambda foo.bar
Generating fresh 'lein new' holy-lambda project.
@borkdude Thank you! Found this works as well: clojure -X:new clj-new/create :template holy-lambda :name basic.core
yeah, that's how you're supposed to use it. See docs
You can put the :exec-fn
in the deps.edn
:new
alias
working with websockets client for the first time: how do I go from java.nio.HeapCharBuffer
to a string or something I can feed to clojure.data.json/read-str
? (I’m using hato
as the client in a backend app, this is not cljs!)
@slack.jcpsantiago (str buf)
?
I had typo :face_palm: ofc that works thanks
what's the state of the art for deps.edn projects when building a cljs client to serve from a clj server? Are we still all using two commands, one each for the client and the server? [ Just want to be sure I didn't miss a memo ]
The server command runs the server - the run time, after deploying. The client command builds the client - the compile time, before deploying. They should not be a single command.
I recall the Swearjure creators ran into the same problem :P https://hypirion.com/musings/swearjure
implementation of hash-map
without alphanumeric characters:
(def my-hash-map
#(`[{~% ~@%&}] (+)))
I would not be surprised if some people create shell aliases and/or tiny shell scripts so they can reduce typing for these kinds of things.
Haha, the things some people invent... I didn't know about Swearjure, truly an excellent mind twister
Definitely! And there's a bit less of a need for that with the recent clj
CLI.
But still - two separate commands. :)
ok - cool, it's how I thought. Thanks @p-himik and @andy.fingerhut
Is it possible to eval a single form inside a comment block in Emacs (Spacemacs)? I use C-c C-c
to eval stuff like function definitions. I have a comment block with something like the following:
(comment
(require 'app.stuff)
(def a-list (app.stuff/get-list))
)
I'm trying to put the cursor on require
and "do something" that will evaluate only (require 'app.stuff)
. I got inspired from "Rich comment blocks" but I must be missing something.
Maybe what I need isn't bound in Spacemacs... but I have no idea of what it is that I'm looking for.I did try cider-eval-last-sexp
which is also bound to C-c C-e
but I didn't understand where I had to place the cursor. Without correct cursor position the result was somewhere between errors and unuseable.
But now that I understand it a bit better I found the following to work:
(comment
(require 'app.stuff)
█ ;; place cursor here and "eval-last-sexp"
;; to "require app.stuff"
(def a-list (app.stuff/get-list))
;; place cursor here and "eval-last-sexp"
;; to define a-list
)
thanks for your help
Maybe ask in the #spacemacs channel? You'll be more likely to get an answer faster in the right channel.
There’s a var for that
Check out m-x apropos toplevel
Also, try putting the cursor on the last paren of require
. Haven't used spacemacs in a while, but that might work a bit better. What function are you running to eval the expression?
(setq clojure-toplevel-inside-comment-form t)
> Eval top level forms inside comment forms instead of the comment form itself. Experimental.
typically what I do is cider-eval-last-sexp
, which in spacemacs' clojure layer is bound to SPC m e e
by default
cI have a problem parsing a xml document. can someone help me? I try to use zippers
https://www.sec.gov/Archives/edgar/data/880195/000175272421030956/primary_doc.xml
(ns edgar.nport (:require [clojure.string :as str] [clojure.xml :as xml] [http://clojure.java.io :as io] ;[clojure.data.xml :refer [parse-str] [clojure.zip :as zip] [clojure.data.zip :as zf] [clojure.data.zip.xml :as zip-xml])) ; zippers ; https://blog.korny.info/2014/03/08/xml-for-fun-and-profit.html ; http://clojure-doc.org/articles/tutorials/parsing_xml_with_zippers.html (defn dl [n-p] (let [node-p (first n-p) tag-p (-> node-p :tag) nodes-c (:content node-p) v-c (for [node-c nodes-c] [(:tag node-c) (first (:content node-c))])] ; {:tag-p tag-p :c (into {} v-c)} (into {} v-c))) (let [r (-> "demodata/a.xml" io/file xml/parse zip/xml-zip) g (zip-xml/xml1-> r :b)] ; g ;(zf/descendants g) (dl g)) (defn dl-p [root & paths] (-> (apply zip-xml/xml1-> root paths) dl)) (def root (-> "demodata/N-PORT/primary_doc.xml" io/file xml/parse zip/xml-zip)) (def gi (zip-xml/xml1-> root :formData :genInfo)) (dl gi) (dl-p root :formData :genInfo) (dl-p root :formData :fundInfo)