@jatkin care to share insight?
Not much, just I now understand the syntax extensions. Made a pseudo xor which works well.
Still confused about _ though. If there is a more detailed explanation Iβd greatly appreciate it ;)
probably would be useful to others still (maybe in the examples doc?) I find myself in the same pattern: struggling with the syntax and "i get it" nirvana when i figure it out
I hope to find time to go back and make a thorough explanation of the things you've run into. Just been a busy few days.
_ just matches anything.
Even an empty space I guess?
_ ... Means zero or more of anything.
So that would include nothing.
That is also why your ?x ... Wasn't working. Because what can we bind ?x to when it matches nothingness?
Huh. I would expect _ to bind to something at least. Good to know though.
It would, if you didn't say the ... It is like .* in regex
You can say ..1 to do at least one element.
Ah, I had a very bad misconception. I thought ... would match nothing. Instead it is a postfix modifier.
[...] is invalid syntax.
Yep exactly right.
haha, I went to make a note about ...
being a postfix operator, and it was already there. Not sure how I missed it the first time. I may have just skimmed that section initially since I thought "of course I know what ...
does, I use it all the time" π
Bingo, thank you very much for that!
It repeats everything till the end or until it hits a dot. [1 . 2 ...]
would match a vector with just a one in it. Or a vector with a 1 followed by a bunch of 2s.
No problem. There is definitely some conceptualizing that has to go on. I struggled quite a bit with meander when Joel first introduced me to it.
If itβs worth anything I have mixed feelings about the syntax myself. I pulled inspiration from many places. The β¦
I borrowed from Racket but I tweaked it a little bit.
Iβm close to having a search interpreter ready for folks to use.
(let [map-search (make-search-fn '{?k ?v :as ?m & ?rest})]
(map-search {:a 1 :b 2 :c 3}))
;; =>
'({?m {:a 1, :b 2, :c 3}, ?k :a, ?v 1, ?rest {:b 2, :c 3}}
{?m {:a 1, :b 2, :c 3}, ?k :b, ?v 2, ?rest {:a 1, :c 3}}
{?m {:a 1, :b 2, :c 3}, ?k :c, ?v 3, ?rest {:a 1, :b 2}})
This is one of the places where if you were attempting to construct a pattern involving ...
itβd be unpleasant.
But I think this is one of the last contributions I want to make to epsilon
and then get back to zeta
.
I think the challenge I'm having is somewhat "curse of its own success"
a lot of times, it looks like magic/i don't have a high level mental model of how it's implemented
so finding myself resorting to rote memorization of syntax/grammar
Yup. I have the same issue. I'm starting to think I'll just need to read the source code to see why it does what it does. Right now all I can say is "magic happens" whenever one of these is compiled. Makes it very hard in more advanced use cases to back out what I should do to get the result I want.
For me learning meander was more akin to learning functional programming than it was for learning aom clojure library. My recommendation is not try to think about what something does or how it compiles but think about what it means. For example a logic variable is bound to one and only one value. It cannot be rebound. It also must be bound for a match to be valid. Given this, if I see two mentions of the same logic variable, I know they are bound to the same value. So I can use logic variables to join. Same thing is true with the top level API of meander. Match accepts a singular deterministic pattern. Search allows for ambiguity and finds all values that satisfy the match. How all these things work isn't something that I thought about. Just like I never thought about how closures work, or how algebraic data types work. I just think about what they are. What properties they have.
Maybe that's up to learning differences? I typically do better using a tool if I can "see" under the hood. I use see loosely as a stand in for "I kind of know how this works, and if I needed to I could write it". I'll definitely try approaching it as learning a top level thing first though. Understanding the code in meander would take quite a while π
Yeah epsilon is not an easy codebase to understand because it was built while exploring the problem. But also because it just does a lot and is complicated. I did try to explain how we are making zeta. https://jimmyhmiller.github.io/building-meander-in-meander Understanding how meanders actual compiler works would probably not help many people. But I do think understanding a straw man interpreter can be very useful.