Fork me on GitHub
#meander
<
2020-02-29
>
timothypratley17:02:32

(m/and ?parameters (m/let [?required-parameters (get-required-params ?parameters)
                           ?optional-parameters (get-optional-params ?parameters)]))
^^ is this the “right” way to introduce bindings? seems a bit weird using m/and + I’m never sure exactly where to “put” the let

👀 4
timothypratley18:02:32

Oh this is pretty sick:

{:parameters [(m/or {:required true :as !required-parameters}
                                   {:as !optional-parameters}) ...
                             :as ?parameters]}

👍 4
timothypratley18:02:20

Seems like there is often a way to avoid using let bindings altogether.

👍 4
jimmy19:02:02

To answer the first question. That is a pretty common idiom we’ve used for introducing bindings. It does feel a little weird. Many times the let body is just empty. Maybe we should think of a better syntax for that.

timothypratley18:02:21

Hmmm something that occurred to me, and I’m sure you’ve already considered about error messages: Currently things like match can take multiple patterns, but I often use them with 1 pattern. In the 1 pattern case; it makes sense when meander encounters “FAIL” to return “FAIL”, what was expected, what was actually there, and where the fail occurred. In the general multiple pattern case that information should be discarded.

jimmy19:02:27

Yeah, I definitely want there to be better error messages. Sometimes it can get tricky with the optimizations we do to surface good information there. But we can definitely easily do better than what we currently do.

timothypratley19:02:44

🤯 wow strategies compose great with m/app even for multi-arg scenarios if you pass vectors:

(def extract-resources
  (s/rewrite
    (m/with [%resource {:methods {& (m/seqable [_ !methods] ...)}
                        :resources {& (m/seqable [_ %resource] ...)}}]
            [?baseUrl {& (m/seqable [_ %resource] ...)}])
    ;;=>
    [(m/app extract-method' [?baseUrl !methods]) ...]))

(def build-methods'
  (s/rewrite
    {:baseUrl ?baseUrl
     :resources {& (m/seqable [!resource-names !resources] ...)}
     :name ?name
     :version ?version}
    ;;=>
    [[!resource-names (m/app extract-resources [?baseUrl !resources])] ...]))
^^ no lambdas required o_O 🙂

parrot 4
aisamu20:02:01

From the cookbook:

(m/match {1 2 3 4 5 6}
  {& (m/seqable [!ks !vs] ...)}
  [!ks !vs])
;; => [[1 3 5] [2 4 6]]

;; But if we remove the map from the pattern, it returns the same: 
(m/match {1 2 3 4 5 6}
  (m/seqable [!ks !vs] ...)
  [!ks !vs])
;; => [[1 3 5] [2 4 6]]
Is that expected?

jimmy20:02:53

Yeah in that example the map wouldn't make any difference whatsoever. Maps are seqable afterall.

👌 4
jimmy20:02:34

Well technically not true

jimmy20:02:48

If you passed the first one something that was not a map it would fail.

jimmy20:02:14

The second one will match on any seqable.

aisamu21:02:09

I can't seem to explain the behaviour of the third case:

;; "Please match everything" - works as expected
(m/rewrite [1 2 1 3 1 4]
  [!xs ...]
  [!xs ...])
;; => [1 2 1 3 1 4]

;; "Please don't match 1's" - works as expected
(m/rewrite [1 2 1 3 1 4]
  [(m/or 1 !xs) ...]
  [!xs ...])
;; => [2 3 4]

;; "Please don't match 1's nor 3's" - ???
(m/rewrite [1 2 1 3 1 4]
  [(m/or 1 3 !xs) ...]
  [!xs ...])
;; => [1 1 3 1]
m/or is suddenly its inverse! What am I missing?

jimmy23:02:45

I'm surprised by this. I will look into it tonight if someone else doesn't first.

jimmy05:03:27

This is a bug not 100% sure the correct fix for this. But should have a fix tomorrow or monday.

aisamu18:03:18

Oh, thanks!

nlessa23:02:19

Hi! Why !(m/rewrite [::a ::b] [!enums ...] ( !enums ...)) is OK and (m/rewrite [::a ::b] [!enums ...] #{ !enums ...}) is not? # has some special behaviour inside meander?

jimmy23:02:11

Sets aren't ordered collections so we can't make ... Work consistently. Can't think off the top of my head the right option there. On my phone will get back to you tonight.

timothypratley23:02:15

(m/rewrite [1 2 3 4 5 6]
  [!x ...]
  #{^& (!x ...)})
;;=> #{1 4 6 3 2 5}

👍 4
metal 4
timothypratley23:02:26

You can use metadata trick

timothypratley23:02:33

(m/rewrite [::a ::b]
  [!enums ...] #{^& (!enums ...)})
=> #{:happy.beaver/a :happy.beaver/b}

timothypratley23:02:17

Because metadata is on the set item 🙂

nlessa01:03:49

thanks Timothy! Nice trick!