Fork me on GitHub
#meander
<
2022-02-01
>
Richie13:02:53

Hey, I’m trying to make the first example work. It doesn’t match when I think it should.

(do
  (m/defsyntax content
    [a]
    `{:content (_ ~a _)})

  (m/rewrite '{:content (no yes no2)}
    (content ?body) ?body))
;; nil

(do
  (m/defsyntax content
    [a]
    `{:content (m/app second ~a)})

  (m/rewrite '{:content (no yes no2)}
    (content ?body) ?body))
;; yes

(do
  (m/defsyntax content
    [a]
    `{:content (m/app type ~a)})

  (m/rewrite '{:content (no yes no2)}
    (content ?body) ?body))
;; clojure.lang.PersistentList
Thanks!

Richie13:02:49

I can do this though:

(m/defsyntax content
  [a]
  `{:content (m/app #(map second (partition 2 2 %)) ~a)})

(m/rewrite '{:content (no yes no2)}
  (content (?body)) ?body)
;; yes

Richie16:02:37

(m/rewrite '{:content (no1 yes no2 yes2 no3)}
  {:content (m/seqable _ ?a _ ?b _)} (?a ?b))
expands to
(let [R__28517 (let [TARGET__28511 '{:content (no1 yes no2 yes2 no3)}]
                 (let [T__28512 (.valAt TARGET__28511 :content)]
                   (if (seqable? T__28512)
                     (let [SEQ__28514 (seq T__28512)]
                       (if (= (bounded-count 6 SEQ__28514) 5)
                         (let [SEQ__28514_nth_1__ (nth SEQ__28514 1)
                               SEQ__28514_nth_3__ (nth SEQ__28514 3)]
                           (let [?a SEQ__28514_nth_1__]
                             (let [?b SEQ__28514_nth_3__]
                               (list ?a ?b))))
                         meander.match.runtime.epsilon/FAIL))
                     meander.match.runtime.epsilon/FAIL)))]
  (if (meander.match.runtime.epsilon/fail? R__28517) nil R__28517))
while
(m/rewrite '{:content (no1 yes no2 yes2 no3)}
  (content ?t1 ?t2) (?t1 ?t2))
expands to
(let [R__28556 (let [TARGET__28550 '{:content (no1 yes no2 yes2 no3)}]
                 (let [T__28551 (.valAt TARGET__28550 :content)]
                   (if (seqable? T__28551)
                     (let [SEQ__28553 (seq T__28551)]
                       (if (= (bounded-count 6 SEQ__28553) 5)
                         (let [SEQ__28553_nth_0__ (nth SEQ__28553 0)
                               SEQ__28553_nth_1__ (nth SEQ__28553 1)
                               SEQ__28553_nth_2__ (nth SEQ__28553 2)
                               SEQ__28553_nth_3__ (nth SEQ__28553 3)
                               SEQ__28553_nth_4__ (nth SEQ__28553 4)]
                           (case
                             SEQ__28553_nth_0__
                             (_)
                             (case
                               SEQ__28553_nth_2__
                               (_)
                               (case
                                 SEQ__28553_nth_4__
                                 (_)
                                 (let 
                                   [?t1 SEQ__28553_nth_1__]
                                   (let 
                                     [?t2 SEQ__28553_nth_3__]
                                     (list ?t1 ?t2)))
                                 meander.match.runtime.epsilon/FAIL)
                               meander.match.runtime.epsilon/FAIL)
                             meander.match.runtime.epsilon/FAIL))
                         meander.match.runtime.epsilon/FAIL))
                     meander.match.runtime.epsilon/FAIL)))]
  (if (meander.match.runtime.epsilon/fail? R__28556) nil R__28556))

Richie16:02:24

where

(m/defsyntax content
  ([a]
   `(m/or {:content (m/seqable ~a)}
          {:content (m/seqable _ ~a _)}))
  ([a b]
   `{:content (m/seqable _ ~a _ ~b _)}))

Richie16:02:00

What’s with

(case
    SEQ__28553_nth_0__
    (_)
That’s checking if it’s uhh… a list of one thing?

Richie16:02:49

I just want it to generate code like

(let [R__28556 (let [TARGET__28550 '{:content (no1 yes no2 yes2 no3)}]
                 (let [T__28551 (.valAt TARGET__28550 :content)]
                   (if (seqable? T__28551)
                     (let [SEQ__28553 (seq T__28551)]
                       (if (= (bounded-count 6 SEQ__28553) 5)
                         (let [SEQ__28553_nth_0__ (nth SEQ__28553 0)
                               SEQ__28553_nth_1__ (nth SEQ__28553 1)
                               SEQ__28553_nth_2__ (nth SEQ__28553 2)
                               SEQ__28553_nth_3__ (nth SEQ__28553 3)
                               SEQ__28553_nth_4__ (nth SEQ__28553 4)]
                           (let 
                               [?t1 SEQ__28553_nth_1__]
                               (let 
                                   [?t2 SEQ__28553_nth_3__]
                                   (list ?t1 ?t2))))
                         meander.match.runtime.epsilon/FAIL))
                     meander.match.runtime.epsilon/FAIL)))]
  (if (meander.match.runtime.epsilon/fail? R__28556) nil R__28556))

Richie16:02:55

that works…

noprompt18:02:31

> That’s checking if it’s uhh… a list of one thing? No, case allows you to group a bunch of cases together with a list:

(let [f (fn [x]
          (case x
            (:a :b :c) "A"
            ;; else
            "B"))]
  [(f :a)
   (f :b)
   (f :c)
   (f :d)])
;; =>
["A" "A" "A" "B"]

Richie15:02:43

Also, I expect the first two to return (yes yes2) and (yes) but I just get nil. What’s wrong here?

(m/defsyntax content
  ([a]
   `(m/or (~a)
          (_ ~a _)))
  ([a b]
   `(_ ~a _ ~b _)))

(m/rewrite '(no1 yes no2 yes2 no3)
  (content ?t1 ?t2) (?t1 ?t2))
;; nil
(m/rewrite '(no1 yes no2)
  (content ?t1) ?t1)
;; nil
(m/rewrite '(yes)
  (content ?t1) ?t1)
;; yes
Thanks again!

Richie15:02:13

Of course this works:

(m/rewrite '(no1 yes no2 yes2 no3)
  (m/seqable _ ?t1 _ ?t2 _) (?t1 ?t2))
Doesn’t help me though.

noprompt17:02:42

I’ll try and take a look at this today. I’ve been busy with work stuff.

noprompt17:02:15

Actually, I have a few minutes now…

noprompt17:02:04

(m/defsyntax content
  [a]
  `{:content (_# ~a _#)})

noprompt17:02:39

(m/rewrite '{:content (no yes no2)}
  (content ?body) ?body)
;; =>
yes

noprompt17:02:50

@rgkirch You need to _# 🙂

Richie17:02:05

What is that?

Richie18:02:39

Ah, it’s in the readme…

noprompt18:02:45

Don’t worry, one day, when the next version is available, maybe this year, we’ll be using rewrite rules to define this kinda thing instead of this macro style thing.

Richie18:02:54

I was going to ask when else I might need it but it’s only used with _# or like %set# in subset-of so I’ll probably never need it outside of _ in defsyntax.

Richie18:02:06

I’m looking forward to that day. I think. I don’t really know what you mean.

Richie18:02:32

I did just notice https://github.com/noprompt/meander/discussions/225 yesterday. Haven’t looked at it yet though.

noprompt18:02:59

Yes, I’m incrementally working on this.

Richie18:02:14

Also, thank you!

noprompt18:02:31

I did a bunch of work and thinking “offline” and now I’m gradually jotting down those thoughts.

noprompt18:02:25

defsyntax will be replaced by defoperator which uses familiar rewrite rules instead of Clojure style syntax quote, etc

(defoperator boolean
  (_) (`some true false)
  (_ & ?rest) (`each (`boolean) & ?rest))

noprompt18:02:34

This looks more like Scheme syntax rules.

noprompt18:02:54

That thread will mostly be for explaining the primitive terms of the pattern language and its interpretation.

Richie18:02:11

Interesting…

Richie18:02:44

I’m not familiar with scheme syntax rules.

noprompt18:02:27

The main reason I’m writing this stuff down is because, at the moment, in my personal life, I’m taking a break from working on Meander and I want to get more people involved such that I don’t get burned out to the point the project dies.

Richie18:02:19

I’d rather you document it so that I can follow along and support it than have you work on it alone. You’re the idea factory, haha.

noprompt18:02:43

Ah, thanks. Actually, a lot of these ideas I’ve borrowed. 🙂 Shoulders of giants and all that.

Richie18:02:06

Oh, and I should mention if I haven’t already. I do want to get involved. I’m still learning epsilon and planning to contribute to the docs sometime.

noprompt22:02:26

Awesome. I think I’m going to set up a meeting maybe once or twice a month or just find time to meet with people who want to contribute as needed.

Richie22:02:52

That sounds exciting!

Richie19:02:45

Ah, auto gensym. Ok.