This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-08-19
Channels
- # announcements (4)
- # asami (1)
- # babashka (48)
- # beginners (84)
- # bristol-clojurians (1)
- # calva (15)
- # chlorine (11)
- # cider (37)
- # clj-kondo (17)
- # clojure (72)
- # clojure-europe (13)
- # clojure-italy (43)
- # clojure-nl (6)
- # clojure-spec (8)
- # clojure-uk (19)
- # clojuredesign-podcast (7)
- # clojurescript (132)
- # code-reviews (7)
- # conjure (3)
- # crux (6)
- # cursive (24)
- # datascript (10)
- # datomic (61)
- # docker (4)
- # duct (24)
- # emacs (2)
- # figwheel-main (8)
- # fulcro (43)
- # graalvm (5)
- # juxt (1)
- # keechma (14)
- # malli (2)
- # off-topic (120)
- # re-frame (111)
- # reagent (6)
- # reitit (13)
- # shadow-cljs (118)
- # spacemacs (3)
- # tools-deps (32)
- # uncomplicate (5)
especially useful for ignoring out kv in a map
{:foo "foo"
#_#_:bar "bar"
:baz "baz"}
not about laziness, about the location that conj
uses, AKA (equivalently) the position that a peek or pop should use, sharing the same underlying constraint: using the efficient position in the data structure for insertion / removal
(on a higher level of design thinking, I think this is more intuitive if you avoid collapsing the queue abstraction of pop/peek and the implementation detail of the collection used)
It might look a bit surprising, but it is consistent. Using pop
, peek
, and conj
, vectors and lists behave like stacks. They do not store data in the same order, but they behave the same when using those 3 fns
right, and the thing to watch out for is any mix of "first" or "last" or "rest" or "next" in the same code that uses peek / pop / conj
these are two different domains that just happen to share a data structure by coincidence
I once had a massive app bug caused by someone calling "rest" instead of "pop" on a clojure.lang.PersistentQueue, therefore turning a FIFO into a LIFO queue and breaking a distributed algorithm
there might have been a change on PersistentQueue that causes rest to return a value that can't be used as a stack to prevent this error
or else my memory is incomplete and there was some other more subtle behavior that made sure that queue which became a seq then became a list
I agree it's consistent, when you know that lists and vectors are implemented in different orders. It's very easy to make mistakes though.
Right, and that's why I offer (the hopefully helpful) suggestion of how to avoid that mistake. It's a tricky failure state of the lispy "small number of data structures and many functions" approach that clojure uses, compounded by its "many composed interfaces on one data structure" design. Both are great decisions with consequences I don't want to do without, but it's good to know the pitfalls to watch out for.
Hi, is it possible to retrieve arity information of an anonymous function using reflection?
Hi, is it possible to retrieve arity information of an anonymous function using reflection?
Are you using Clojure? If so, you can just use meta
(see :arglists
):
user=> (meta #'clojure.core/map)
{:added "1.0",
:ns #object[clojure.lang.Namespace "0x27b1284f" "clojure.core"],
:name map,
:file "clojure/core.clj",
:static true,
:column 1,
:line 2727,
:arglists ([f] [f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]),
:doc "Returns a lazy sequence consisting of the result of applying f to\n the set of first items of each coll, followed by applying f to the\n set of second items in each coll, until any one of the colls is\n exhausted. Any remaining items in other colls are ignored. Function\n f should accept number-of-colls arguments. Returns a transducer when\n no collection is provided."}
Thank you! Unfortunately I'm working with anonymous functions at the moment, so there does not appear to be any available meta-data.
(->>
(fn ([a b]) ([a b c]))
clojure.reflect/reflect
:members
(filter (comp #{'invoke} :name))
(map (comp count :parameter-types))
(into #{}))
Be advised its performance is probably trash so I hope you don't use it on your hot path
https://github.com/littleredcomputer/sicmutils/blob/master/src/sicmutils/value.cljc#L269
if you use the cljs version in there, know that it won't work in advanced compilation mode
maybe this is an x-y problem. i'm wondering about best practices for registering new :event-id
handlers. is it better to register event handlers next to the business logic, or to register all event handlers in a distinct namespace, importing the business logic?
I wouldn't describe this as sente specific, I was reminded how sente worked from other recent questions
yeah, that's why I said x-y problem. very often i don't know the best question to ask!
people in tech underestimate the power of being an intuitive / empathic conversationalist IMHO, the failure states are usually easy to recognize, and the benefits are big
perhaps with a multimethod instead of a router (a more general and less complex abstraction)
of course if you also don't know how you'd want to organize ring handlers, that's a further conversation topic :D
ha i don't know much about that either, so any resources you have would be good! I inherited/took over development of this app, so there's been a lot of learning as i go
right now, our routes are set up as (-> routes auth/wrap-user wrap-keyword-params ...etc)
, where routes
is a compojure defroutes
object
so with a multi-method approach, i'd define the defmulti
in the core namespace, and then in the implementing namespaces, defmethod
?
you can wrap the defmulti in a middleware stack the same way you would a router, but it's simpler than a router
you could also put interceptors on it the same way you would in pedestal, these are very reusable techniques IMHO
Iโll second the recommendation to do one of those things. As your event handlers start proliferating, youโll start noticing that you want to extract common patterns (like permission checks etc.), and middleware/interceptors are really useful there.