This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-09-24
Channels
- # announcements (6)
- # architecture (9)
- # aws (2)
- # babashka (49)
- # beginners (160)
- # boot (19)
- # calva (9)
- # cider (16)
- # clj-kondo (17)
- # cljfx (9)
- # clojure (143)
- # clojure-australia (5)
- # clojure-berlin (1)
- # clojure-czech (3)
- # clojure-europe (64)
- # clojure-france (1)
- # clojure-italy (12)
- # clojure-nl (4)
- # clojure-spec (6)
- # clojure-uk (47)
- # clojurescript (27)
- # code-reviews (5)
- # conjure (45)
- # cursive (47)
- # datascript (2)
- # datomic (21)
- # events (1)
- # fulcro (9)
- # graalvm (4)
- # graphql (2)
- # jackdaw (22)
- # jobs (3)
- # kaocha (6)
- # london-clojurians (1)
- # luminus (4)
- # malli (19)
- # meander (136)
- # pathom (4)
- # pedestal (2)
- # re-frame (15)
- # reitit (2)
- # remote-jobs (2)
- # rum (12)
- # sci (1)
- # shadow-cljs (100)
- # spacemacs (10)
- # sql (1)
- # tools-deps (30)
- # vrac (1)
- # xtdb (30)
what's up with clj-kondo in vscode, it seems like it can't see dependencies and fill up files with unresolved symbols in the editor
I hope you are using the Calva extension for VSCode, there is another Clojure extension that is not as capable Recomend using https://marketplace.visualstudio.com/items?itemName=betterthantomorrow.calva
hopefully the nice people on #calva can help you if you are still having issues.
@clypto Probably a better question for #clj-kondo and/or #vscode / #calva ?
(although it sounds like you haven't run the project initialization for clj-kondo
per the README?)
Er, the clj-kondo
readme?
Yeah, I had to blow away the .clj-kondo/.cache
folder in one of my projects today and re-run the parallel lint initialization thing again because it got stuck thinking a couple of functions had different arities after some refactoring...
If you refactor using the same editor that should not happen, since it lints files when editing and the last refactored file has the last known valid arities
Hey folks, I'm struggling a bit with variadic functions this morningâ I have a function defined like:
(defn create-node [node-type props & children]
...blah)
And then I have a call site where I write (create-node "x" {})
, and when I run the cljs compiler I get "wrong number of arguments passed to create-node"Why is that the wrong number of arguments? I want that call to be valid and for children
, in that case, to be an empty list
I donât remember the answer to your question about arity, but the âcreate-nodeâ name reminds me of a bug I ran into where I used a variadic argument to pass in some child nodes, and it blew up as soon as I tried to create a node with a large number of children. Thereâs a limit on the number of arguments a Java method can accept, so just a caveat in passing.
I just tried taking the list of children manually instead of via a variadic parameter, and I'm hitting the same "wrong number of argugments" still
Could be, depending on how itâs recursing
Your original defn looks correct to me, fwiw
Whatâs the exact text of the error? It should tell you how many args it was expecting vs how many it got.
It works for me ... Is create node recursive? Is there something in ...blah
that's actually causing the error?
% clj --main cljs.main --repl
ClojureScript 1.10.758
cljs.user=> (defn create-node [node-type props & children] :blah)
#'cljs.user/create-node
cljs.user=> (create-node "x" {})
:blah
cljs.user=>
Ok, thatâs sounding like your REPL has stale code stuck in it somehow, can you restart?
oh, derp, yeah, I missed that, good catch
or name your function something different
Apparently cljs at least does.
Try (doc cljs.core/create-node)
also, side question, is there a good way to accept a variadic children
or an explicit list of children?
it seems my best bet would be to make that definition be [node-type props & children]
but then check if the first element in children
is itself a list. If it is, use that as my children
array?
I would recommend not doing that and just picking one or the other
Itâs just easier to understand and maintain
@alexmiller thanks, definitely agree, but I would like to enable syntax like (create-node "x" 1 (create-node "y" 2))
while also enabling syntax like (create-node "x" 1 (map (fn [child] (createNode...)) (range 10))
yknow what I mean?
Maybe there's some macro sugar I could use to enable this while preserving a singular notion of create-node
's interface
I generally agree with others clucking their tongues over this, but for geenrating children it is definitely mad useful to be able to supply an atom or list or even nested list and then Just Flatten(tm) the input. The one constraint of course is being sure we can live with flatten
! In my fav use case I am building children for a UI/Dom node and I know flatten will stop when it gets to a node, and also I knw the parent demands a flat list of child nodes. Now I can bung together whatever I want creating children and have it all flattened before hitting the parent. hth
I will check now on what clj flatten
does. (I have my own from my CL days.)
Ah, no, (flatten 42)
=> nil, we want 42.
Hereâs my wrapper for any thing from an atom to a nested list of atoms. The *par*
bit can be ignored. The doall
is likewise sth specific to my usage. Note that the rest arg guarantees some list will be seen by the innards to avoid the flatten
discard of atoms. Oh, and we gracefully handle some nested generator deciding not to create any nodes, a classic in reactive/dynamic UIs, and discard nils.
(defmacro the-kids [& tree]
`(binding [*par* ~'me]
(assert *par*)
(doall (remove nil? (flatten (list ~@tree))))))
or make two fns
@nickt In that case I would make create-node accept always a list of children. [(create-node ...)]
is not much more typing than (create-node ...)
. or indeed create another fn
that's probably what I would do as well (list)
you could have something like INode
where you represent multiple children as a NodeSeq
which implements INode
so passing multiple or one is valid in terms of your model
about passing props: easier parsing, passing, etc
hmm ok, lot for me to think about. Thanks @borkdude and @alexmiller
Is there a better way to use a different default printer than just starting a subrepl? for example if I want my repl to always use https://github.com/brandonbloom/fipp to print, I have the following evaluated when I start a repl:
...
(:require [clojure.main :as main]
[fipp.edn :refer [pprint] :rename {pprint fipp}]
[fipp.repl :refer [pst]])
...
(main/repl
:caught pst
:print fipp
)
This works ok but then there are some times where it does cause subtle issues and it takes awhile to remember to try without fipp. Is this inevitable? I'm currently using inf-clojure on emacs.CIDER uses fipp for all projects if you set it as the default
(setq cider-pprint-fn 'fipp)
Does the editor you are using support something similar?
Does anybody know any good way to parse nested query strings in Pedestal?
It is currently able to automatically turn qs in maps (`?q=1&b=2` => {:q 1 :b 2}
), but I would need something a little bit more elaborate, such as ?foo[bar]=baz
=> { :foo {:bar "baz" } }
Yes I do @vlaaad; I can reshape it in case there's a format that Pedestal will deserialise automagically
I would regularly use a body, but this is a GET call and I want to go through a query string
this is a dangerous idea if youâll want to make this endpoint consumable by other clients as well
idk, I guess I can see the argument for, âEDN doesnât have an encoder in every lang.â
Is there a way to declaratively set a spec check on a payload in Pedestal or shall I manually put this boilerplate every time? https://github.com/XVincentX/clojure-playground/blob/master/src/app/core.clj#L21-L23
I would write an interceptor to do that
Ok thanks @U0DUNNKT2 â I was thinking about the same, just wondering if Pedestal had something out of the box
There is likely a library that provides such an interceptor, but I'm not sure how worthwhile it would be to bring in a dependency for that. Shouldn't be more than a few lines of code, and it's nice IMO to have full control over the behavior.
@U0DUNNKT2 Here it is. Likely not the best code ever, but it does the job.
Looks good overall. A few small suggestions:
* If you want to terminate request processing early, it's good practice to use terminate
(http://pedestal.io/api/pedestal.interceptor/io.pedestal.interceptor.chain.html#var-terminate).
* You might consider doing something like (assoc-in context [:request :parsed qstring] parsed-param)
so that you're just adding data to your context map in the interceptor and not overwriting your request data.
* Consider the option of separating the concerns of parsing the query params and validating them into separate interceptors.
Also, there's a #pedestal channel that might be a good place to discuss further.
All good point. I've read somewhere that Pedestal terminates if the response object is there, that's why I followed the convention
@U0DUNNKT2 I do not understand the second point â how would assoc overwrite the request data?
I'm not a pedestal expert and it's been a while since I've used the library. IIRC the request data is available in ctx
under the :request
key. If that is the case and you do (assoc ctx :request {:parsed parsed-param})
, then you will dump whatever data was previously associated to :request
. If that's not what's happening, then there is no problem. :)
Hello guys! I made a reservation system. The mechanism is: 1. read from mongo->decide if there is free space 2. if free, insert reservation, if not free, don't. This function is called add-reservation
. My problem is, add-reservation
is behind a server. I would need the to run only one add-reservation
at a time, because there is a concurrency problem when multiple run at once. I use agent
and send reservations to it. Is there a better way?
well, locks are fine if you need one. an agent is a good solution, assuming you have only one server
Definitely, locks only make sense if you have more than one server. Maybe I misunderstood the question :thinking_face:
Hello! Quick question: whatâs the term for an aggregate (e.g. a sum) that isnât declaratively specified, but instead is updated imperatively on every event? e.g.
total_payroll = select sum(salary) from employee;
v.s.
total_payroll = 0
on insert employee, total_payroll += salary
on delete employee, total_payroll -= salary
on update employee, total_payroll += (new_salary - previous_salary)
I know there is a term for it but I forgot what!running total? rolling sum?
I'll check the locks too! thanks!
@paul931224 Maybe not super helpful if its set in stone, but Mongo probably isn't the best database for this
you will run into more scaling problems trying to have what would effectively need to be a distributed lock on the reservations collection than with scaling a sql db
if you don't need to scale ever and really can just have a single server for all time then server side locks would be just fine
namespace and protocol question: i have a protocol CostFns
in game.core.abilities
, and then (:require [game.core.abilities :refer [CostFns]])
it in game.core
. I wrote a factory function to store the records that implement these in a var, so I can pass in a keyword to get the right record out, and if I print out the calls, the var is correctly filled during compilation. However, at a later point during compilation an error is thrown, saying that No implementation of method: :cost-name of protocol: #'game.core.abilities/CostFns found for class: game.core.Click
has anyone run into something like this before?
yes, you've reloaded the protocol at some point
ah, okay
the protocol, when compiled, makes a Java interface and the records implement that interface
if you reload the protocol, you make a new interface (same name), and the old records don't implement it
oh interesting, okay. thank you
hey all. Another quick question... I'd like to write a macro that takes N arguments such that if the first argument is a map literal, do nothing, otherwise inject an empty map at the front of the N arguments list. Seems straightforward enough, but how do I check the type of that first argument in a macro?
that's only possible if the map is a literal, you can't check the type of an arg otherwise, it's just a symbol, you don't see the value the symbol resolves to locally until runtime
of course the map being added to the arg list could be done at runtime, you just need to emit code that checks and modifies the arg list in that case
(defmacro foo-bar [& args] `(let [arg-list# (if (map? (first ~args)) ~args (cons {} ~args))] ...))
ok unrelated question: I'm aware of list?
and vector?
. Is there a similar predicate that is true if either list or vector?
(fn [o] (or (vector? o) (list? o)))
perhaps you want sequential?
that is also true for lazy-seqs and conses, which are not lists and are false for list?
in fact, list?
is so rarely useful I consider it a smell in code review
oh, duh, map?
won't work for me in that argslist check because all of the args will be maps heh. What's the idiomatic way to basically "type" a map? As in define a map as a type A or not
you could have a special key or metadata, or use defrecord to have a map with a named type
how does that first map have to be different from the rest?