This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-03-10
Channels
- # announcements (1)
- # babashka (44)
- # beginners (188)
- # calva (37)
- # chlorine-clover (28)
- # cider (12)
- # clj-kondo (40)
- # clojars (1)
- # clojure (323)
- # clojure-austin (7)
- # clojure-europe (20)
- # clojure-italy (4)
- # clojure-nl (16)
- # clojure-spec (7)
- # clojure-uk (37)
- # clojuredesign-podcast (1)
- # clojurescript (30)
- # cryogen (2)
- # cursive (30)
- # data-science (1)
- # datomic (26)
- # emacs (1)
- # events (1)
- # figwheel-main (13)
- # fulcro (89)
- # garden (1)
- # graalvm (20)
- # graphql (8)
- # jobs (1)
- # jobs-discuss (1)
- # joker (6)
- # kaocha (125)
- # lambdaisland (1)
- # meander (42)
- # off-topic (18)
- # pathom (3)
- # pedestal (6)
- # shadow-cljs (55)
- # spacemacs (21)
- # sql (18)
- # tools-deps (8)
- # uncomplicate (2)
- # vim (1)
- # yada (3)
Hey! I am struggling to express a pattern. For instance we could have 1 even number followed by 0 or more odd numbers, this pattern repeating in a sequence like in [2 3 5 4 3 2]
. The goal would be to get in this example something like [[2 [3 5]] [4 [3]] [2[]]]
Any ideas ?
There is a partial solution to this problem but, actually, what we really need to do this properly is a greedy version of …
(basically Kleene star which …
is not that). I would use vanilla Clojure for this in the interim.
Ok thanks, I gathered the pattern It has a regex feel to it, it might be expressed by (ab*)*
. I had a partial solution that identify the first pattern, something like
(-> [2 3 5 4 5 3 6]
(m/search
(m/seqable (m/pred even? ?e) .
(m/pred odd? !os) ...
& (m/and ?rest
(m/or
(m/seqable)
(m/seqable (m/pred even?) .
(m/pred (constantly true)) ...))))
{:e ?e
:os !os
:rest ?rest}))
wondering if I could have use some catamorphism magic on ?rest but I am not used to meander yet and some operator are a little mind bending at first. Plus my solution feels a bit cumbersome compared to the regex. Now I know I can’t really express it. Thanks a lot!So the partial solution uses rewrite
and cata
but due to not having a greedy star or grouping it, and the way rewrite
works presently I can’t, in honesty, recommend it.
(m/rewrite [2 3 5 4 3 2]
[] []
[(m/pred even? ?even) . (m/pred odd? !odds) ..!ns & ?rest]
[[?even [!odds ...]] & (m/cata ?rest)])
;; =>
[[2 [3 5]] [4 [3]] [2 []]]
(It could use seqable
here.)
The zeta
branch will have both grouping and greedy star. I think I can bring greedy star to epsilon
but I’m not sure about grouping.FWIW, I’m spending time working on zeta
and less time on epsilon
because its easier to build a better, less buggy implementation that reflects the breadth and depth of knowledge that I acquired while working on epsilon
. In the spirit of transparency, I’m learning 🙂
True story I made this before seeing your cata:
(m/rewrite [2 3 5 4 3 2]
(m/with [%p (m/or [(m/pred even? !x) . (m/pred odd? !y) ..!n & %p]
[])]
%p)
[[!x [!y ..!n]] ...])
oh damn, my verison drops the last thing though
=> [[2 [3 5]] [4 [3]]]
@U06MDAPTP when you say “I can’t recommend it” about your m/cata
solution…. why not? seems good to me???
Is it that “greedy Kleene” would be more efficient? concise? (Maybe I should just wait and see 🙂)
@U06S1EJPL …
is not greedy. You can think of …
as a gradient from the least to most amount of greed with respect to context. So its really designed for ambiguity when two or more …
patterns are next to each other.
Greed is really about how much to consume and not so much about efficiency or concision.
For example
;; Using infix * to demo
[!xs * !ys ...]
;; or
[!xs * !ys *]
should always starve !ys
by consuming everything because the semantics of *
are greedy.The same would apply to +
by comparison to ..1
. These are not expressing the same idea, at least to my mind they aren’t.
I must apologize to everyone on the face of the earth for not recognizing this subtle difference sooner. 🙂
Ah well I don’t disagree with you… but I’m not seeing how it affects expression of this particular problem. In this case it seems like greediness isn’t a factor as there is only one solution.
Don’t get me wrong; I love regexs and like the sound of what you are saying, I just don’t get it 😄
Oh I think I see what you mean now
is there a situation where you really want non-greedy? I guess for search
maybe?
I guess somewhat ironically …
in match means non-greedy but …
in search means greedy if you have enough constraints o_O I know it doesn’t really mean greedy but you can make it behave like that obviously as per example.
FYI someone asked about having Mathematica’s Longest
and we will have that in the form of greedy Kleene start both on epsilon
and zeta
.
I also want to thank everyone, again, for the millionth time for supporting the project and suffering lows. 🙂
Hey I’m wondering if it’s possible to extract the structures that one passes to the match
function.
Eg.. I tried something like this:
(def match `{:a ?a :b ?b})
(def target `{:a ?b :b ?a})
(m/match {:a 1 :2} ~match ~target}
This produced an error:
> non exhaustive pattern match
defsyntax 🙂
(m/defsyntax m [] '{:a ?a :b ?b})
=> #'happy.beaver/m
(m/defsyntax t [] '{:a ?b :b ?a})
=> #'happy.beaver/t
(m/match {:a 1 :b 2}
(m)
(t))
=> {:a ?b, :b ?a}
Hmmm I was wondering about this. Thanks @U06S1EJPL
Hi @ezmiller77 👋 Someone opened a ticket with a similar structure a while back and the tl;dr to this is “no” and the reason why is that ~expr
is an equality check against the match target with respect to the result of expr
. Its not for splicing patterns.
There is work on going in the subsequent branch of the project, zeta
, which will allow for this kind of programatic thing.
I see. So basically my use-case here has to do with keeping code readable. So maybe I can just pack the expression inside another fn.
I’m basically trying to use meander to do a large-scale remap of keys on a map, where I’m also adding a bunch of other keys with nil
values.
So both the lhs and rhs expressions are gonna be quite large.