Syntax proposal: m/rec
shorthand for m/with
single case
#184
Replies: 13 comments
-
I think this is a cool idea but I want to give it a little thought. I think we could experiment with this on {:m !m, :r m/@r :as m/@r} If I'm being totally honest, I don't really like the namespacing the like this. It's just noisy as hell. Plus, the reader doesn't parse something like {:m !m :r @r ::m/as @r} looks much better to my eyes than the former example. @SevereOverfl0w Had recommended we hold off on using the @jimmyhmiller What do you think? |
Beta Was this translation helpful? Give feedback.
-
Ah, FWIW I'm highly suspicious of Just brainstorming alternatives here: Maybe we don't even need a special name?
|
Beta Was this translation helpful? Give feedback.
-
Yes.
Yeah, that's an unbound reference error. 😄
I'm curious, what about |
Beta Was this translation helpful? Give feedback.
-
@timothypratley If you're looking to cut down a bit you could do something like this in the meantime: (m/defsyntax rec [reference pattern]
`(m/with [~reference ~pattern]
~reference))
(rec %r {:m !m :r (m/or %r {}}) |
Beta Was this translation helpful? Give feedback.
-
Oh - that is really nice! I think that is better than adding a new sigil.
Well, you originally wanted to use it to match
As a side note on sigils, is |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
I don't think it's a good idea to introduce new syntax for such a narrow use-case, especially when it's simply sugar for a more explicit form. Besides, this forces one to put the base case (m/with [%r {:m !m, :r (m/or nil %r)}]
%r) instead of the more sensible (m/with [%r (m/or nil
{:m !m :r %r})]
%r) For instance if (m/match [1 2 [[3] 4 {:value 5 :rest [{:value 6 :rest []} 7]}]]
(m/with [%r (m/or
(m/and (m/pred number?) !n)
(m/seqable %r ...)
{:value !n :rest %r})]
%r)
!n)
;; => [1 2 3 4 5 6 7]
|
Beta Was this translation helpful? Give feedback.
-
@yuhan0 @noprompt I agree that the original proposal has some limitations which make it less useful to |
Beta Was this translation helpful? Give feedback.
-
I don't know, it's useful but feels like the sort of thing which the user should define for themselves with |
Beta Was this translation helpful? Give feedback.
-
That's of course just my personal opinion as a user of the library - with DSLs there's always a tradeoff between a small/restrained vs large/expressive vocabulary. I really like the way Meander is designed so far with a relatively small set of "primitives" and powerful ability to extend them via defsyntax, eg. I've been using my own |
Beta Was this translation helpful? Give feedback.
-
This is all fantastic discussion. I'm on the fence about adding it to core proper. What convinced me to proceed with adding (m/map-of (m/pred string?) _) as {(m/pred string?) _} Of course, once you're skilled with the library, its easy to know how to write this down the latter with We can leave this issue open and sit on it. If it comes up enough, yeah, let's add it. |
Beta Was this translation helpful? Give feedback.
-
I would probably match on 'clojure.core/deref for what I'm doing anyway 🤔. I think this is probably fine. As long as there's never any confusion about when I'm actually derefing. |
Beta Was this translation helpful? Give feedback.
-
If Meander had a slick way to express recursion, it would open up a whole new class of expressions that could be written directly as patterns. Meander already has Yes, I can express recursion with them. Here are 3 approaches to solving the same problem, one with (m/rewrite {:resources {:r1 {:methods {:m1 "m1"
:m2 "m2"}
:resources {:r2 {:methods {:m3 "m3"}}}}}}
(m/with [%p {:methods (m/seqable [_ !methods] ...)
:resources (m/seqable [_ %p] ...)}]
%p)
[!methods ...])
(m/rewrite {:resources {:r1 {:methods {:m1 "m1"
:m2 "m2"}
:resources {:r2 {:methods {:m3 "m3"}}}}}}
{:methods (m/seqable [_ !methods] ...)
:resources (m/seqable [_ !resources] ...)}
[!methods ... & (m/app #(apply concat %) ((m/cata !resources) ...))])
((def zzz
(s/rewrite
{:methods (m/seqable [_ !methods] ...)
:resources (m/seqable [_ !resources] ...)}
[!methods ... & ~(mapcat zzz !resources)]))
{:resources {:r1 {:methods {:m1 "m1"
:m2 "m2"}
:resources {:r2 {:methods {:m3 "m3"}}}}}}) Observing from the three different approaches:
The idea behind
So as to avoid collision with
(m/and %p {:methods (m/seqable [_ !methods] ...)
:resources (m/seqable [_ %p] ...)})
I agree that there should be a goal to keep the set of operators as small as possible, but I also think it is worth comparing notes on recursive expressions and searching out opportunities to apply Meander in recursive scenarios. |
Beta Was this translation helpful? Give feedback.
-
A more concise way to express
Beta Was this translation helpful? Give feedback.
All reactions