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-clover (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)
- # 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)
- # xtdb (6)
Yeah really convenient sometimes.
especially useful for ignoring out kv in a map
{:foo "foo"
#_#_:bar "bar"
:baz "baz"}
and the obligatory
{#_#_#_#_#_#_:foo "foo"
:bar "bar"
:baz "baz"}
Not super intuitive:
user=> (pop '(0 1 2))
(1 2)
user=> (pop [0 1 2])
[0 1]
Because of lazy lookup for lists and “latest item” for vectors right?
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
I probably wasted a month on that!
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.
if that makes any sense
That rest/pop-bug on PersistentQueue sounds like a nightmare
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
@U1SB9U10C I actually might be able to help here!
https://github.com/littleredcomputer/sicmutils/blob/master/src/sicmutils/value.cljc#L269
this should give you what you need on anonymous fns
for sure
if you use the cljs version in there, know that it won't work in advanced compilation mode
but pretty good up to that!
👋 I’m here! What’d I miss?
where's the best place to ask questions about the websockets library sente?
wow, so many sente questions coming up
lol maybe we need a channel!
was completely unintentional, didn't even realize my own genius
asynchronous genius
sometimes it takes a bit 😉
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
very true
and many of those failure states are softened / circuit broken by humility
put that into an AI and you don't need me around any more
hahaha maybe some day
(since I so often fail to do all those things well)
I'd do it in the same basic pattern you'd use with ring handlers and namespaces
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
?
that's how I'd do it yes
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.
hm! i gotta read up on those. thanks for the help
how can i add a typehint for just clj in a cljc file? i was hoping (defn #?(:clj ^java.util.Date) foo [] ...)
does expanding to foo and repeating it help?
it's slightly repetitive but should do the right thing
there's also ^{:tag #?(:clj ... :cljs ...)}
but I think name twice is better