paulstansifer / unseemly

Macros have types!
http://unseemly.github.io/
MIT License
131 stars 5 forks source link

MBE reform #45

Open paulstansifer opened 3 years ago

paulstansifer commented 3 years ago

First: Don't store repeats together. Instead of

   leaves: Assoc<Name, T>,
   repeats: Vec<Rc<Vec<EnvMBE<T>>>>,
   leaf_locations: Assoc<Name, Option<usize>>,
   named_repeats: Assoc<Name, Option<usize>>,

have

  leaves: Assoc<Name, T>,
  repeats: Assoc<Name, Vec<EnvMBE<T>>>,
  repeat_groups: Vec<HashSet<Name>> // Each set is a group of names that must have the same length

or even

  data: Assoc<Name, Stars<T>>
  repeat_groups: Vec<HashSet<Name>>

where

enum Stars<T> {
  Leaf(T),
  Rep(Vec<Stars<T>>)
}

or

struct Stars<T> {
  Vec<T>,
  Vec<usize> // some kinda packed representation of repeat structure I haven't figured out yet
}

(maybe we should drop the concept of named repeats entirely, but this issue is supposed to be semantics-neutral)

Then: Let's make MBE-related operation more composable. Instead of parts.map_reduce_with(parts2, mapper, reducer), we should write EnvMBE::zip(parts, parts2).map(mapper).reduce(reducer)

If this makes performance significantly worse we should (sigh) introduce something analogous to an iterator for MBEs.

Also: I think that MBE in this name doesn't really make sense. The variety of things that we're calling "dotdotdot" have more to do with Macro By Example than this does. Maybe StarEnv? Starsoc?

And then (#38) it seems like we'll replace Vec with ExampleVec... hope this actually winds up being a simplification!

paulstansifer commented 3 years ago

Named repeats (actually, repeat groups; they don't need to be named) can't go away. For Custom walks, we can rely on the user naming all of the repeats that need to be walked together, but for LiteralLike walks, we need the walk process to automatically co-march everything in the same group. The only place that tests enforce this is mu_type, but for a clearer example, imagine a match that's been quoted (so we're walking it LiteralLike); we need each arm to import from its pattern; we don't want to rewrite those imports to import from all of the patterns together.