This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-08-20
Channels
- # admin-announcements (1)
- # announcements (1)
- # beginners (115)
- # calva (31)
- # cider (25)
- # clj-kondo (47)
- # cljdoc (23)
- # cljs-dev (5)
- # clojars (1)
- # clojure (60)
- # clojure-australia (1)
- # clojure-europe (23)
- # clojure-nl (3)
- # clojure-norway (2)
- # clojure-spec (3)
- # clojure-uk (18)
- # clojurescript (49)
- # community-development (1)
- # cursive (4)
- # datahike (2)
- # datascript (3)
- # datomic (36)
- # deps-new (2)
- # emacs (2)
- # events (9)
- # fulcro (6)
- # graphql (2)
- # gratitude (13)
- # holy-lambda (1)
- # introduce-yourself (10)
- # macro (2)
- # malli (5)
- # meander (9)
- # news-and-articles (5)
- # nextjournal (1)
- # off-topic (32)
- # pathom (17)
- # pedestal (13)
- # polylith (4)
- # protojure (4)
- # reagent (4)
- # sci (27)
- # shadow-cljs (2)
- # show-and-tell (2)
- # specter (3)
- # tools-deps (7)
- # xtdb (16)
Hey, are there any ready made cookie-based user authentication options available for Clojure?
what is the and co?
It was quite a long time ago, but I got to the conclusion if want to have it good write it yourself
Okay, thanks.
Hi there, has anyone ever had trouble picking up POI on the classpath while working with Docjure? Deps are installed, so I can't see why it's not able to be loaded.
typically with clojure we don't install deps, we use a dependency manager which caches deps and calculates a classpath including the cached artifact
if you literally mean installing the dep (eg. via OS package manager) I have not successfully used debian installed java libraries with clojure, and it always ends up being easier to use the dep manager (eg. clj or lein) to add the dep
One of the interesting things I've seen with e2e tests is allowing the driver to inspect the client state directly to make assertions and drive the tests.
Pulling the client side state in our app is as easy as
(defn- get-state [driver]
(read-string
(api/js-execute driver "return window.getState()")))
We've been using https://github.com/igrishaev/etaoin at work and it seems to work pretty well.
I've got an interesting algorithm I'm trying to convert into Clojure. the algorithm is constructing a graph. I want to be able to stop and resume constructing the graph at any leaf. the way I'm reading it done in the mutable lang (JS) is by keeping two top-level references: the root of the graph and the node to be worked on. it then mutates properties on these nodes to keep references to their parent, child and siblings as they do work to form the graph.
I'm trying to figure out if there's a clever way to handle this in an immutable way before I resort to a bunch of ref types or using mutable fields :<
it kind of feels like a zipper but I've only ever used a zipper to search and modify leaves, not construct an entire tree starting from the root
It still won't save you form mutating data if you need to pause and resume processing on the very same data.
But if you can change the reference to the data like you'd do with regular assoc
, you can do what JS does, in pretty much the same way, no?
the reference identity isn't important but what I'm stuck on is trying to imagine what kind of structure would allow me to stop and resume it
you can definitely do this with zipper.
It's not a tree, it's a graph, so just having reversed or two-way references won't work if the path is important. You need to record the path. A zipper is indeed fine. But if any branch within a node can be identified with a single unique key, then just a vector of such keys will work as well.
you could also use any of the graph libraries like ubergraph/loom
not sure if your graph will have cycles, but if it does, it seems like using zippers would be cumbersome
So, why not just a vector path? Something like [:a :b :c]
for a tree that's just {:a {:b {:c 1} :d 2} :e 3}
?
I think that's basically what zippers do they just have more algebra already done for you
Not sure what's mean by algebra here. They don't have anything that's not simple up/down/left/right navigation with some mutation.
If your tree doesn't have a concept of left and right siblings, then zippers won't be a good fit IMO. In the above toy tree, that's exactly the case. What's the path "down from :a
"? There's no such thing. What's the path "to the left of :d
"? Again - no such thing.
But if your tree is more similar to a nested vector, then zippers might be more suitable. Although vectors are still associative, you can store a vector of indices as path.
> They don't have anything that's not simple up/down/left/right navigation with some mutation. zippers are immutable
FWIW, I did include some https://cljdoc.org/d/rewrite-clj/rewrite-clj/1.0.644-alpha/doc/user-guide#_a_brief_introduction_to_zippers in rewrite-clj user guide - if that helps your zipper journey at all.
> What's the path "down from `:a`"? There's no such thing. it's easy to define a zipper navigation that does exactly this
> zippers are immutable
That's just poor wording on my end. I mean that there are things like assoc
but for zippers.
I understand what you mean p-himik. In my case, my tree has left and right siblings. to show my hand, it's a React fiber tree - so fibers that represent elements on the page have quite a bit of metadata about them and have siblings, children, etc. I'm guessing if I go about trying to do the book keeping myself, I'm going to end up recreating zippers from scratch - which would probably help me understand them more, but I want to be lazy on my three day weekend 😛 so I'm going to try and grok zippers a bit better first.
If zippers don't work out, try some kind of lenses, you can often get something very zipper like but a little more customizable
it looks like reconcile-node
could probably be simplified to:
(zip/edit loc perform-work)
ah good tip. I've added more to it now, but I could probably move that into perform-work
having gone down the zipper route, I am now wishing that zippers had a built-in way to maintain some information in the context as it traversed the tree
per node context? or just general context?
I tend to use the zipper operations as low level ops and use them to create higher levels ops that more directly fit my use case.
Is the flow of information/context Root-> leaves Leaves-> root Or bidirectional ? @lilactown
it's about building the tree itself. I have some config that would change how the tree is constructed, and I'd like it to be associated with the in-progress tree I'm constructing with a zipper
I guess for now I'll keep a bookmark:
{:config <config>
:wip-tree <zipper>}
and if I come back later I can pass that to a function that will thread config
through to the functions used to build the treeDepends a lot on your algorithm of course, but I think I’ve dones something like that. My use case was modifying an existing tree, though.
Pattern we just started adopting but we are pretty confident is going to start paying dividends
make a file for assumptions we make about our data model that aren't necessarily apparent in our data model