regex icon indicating copy to clipboard operation
regex copied to clipboard

impl Default for RegexSet?

Open sourcefrog opened this issue 3 years ago • 3 comments

Describe your feature request

Would it be reasonable to impl Default on RegexSet, returning an empty set as if it was constructed from an empty list?

This would be helpful when using it inside a struct for which I want to derive Default.

sourcefrog avatar Sep 21 '22 17:09 sourcefrog

The question that immediately comes to mind here is, "why does RegexSet have a Default impl, but Regex does not?"

I guess the answer to that is that a set has a natural default value: the empty set. And an empty set never matches anything. But I would suppose a Regex could also have a default value, either perhaps the empty string (matches everywhere) or even a regex that itself never matches (i.e., an empty character class).

BurntSushi avatar Sep 21 '22 17:09 BurntSushi

I think it just feels weird to me to construct an empty RegexSet just because it's convenient. Why not use an Option<RegexSet> instead?

BurntSushi avatar Sep 21 '22 17:09 BurntSushi

My current code does in fact use an Option<RegexSet>, but it just feels a bit repetitive to say "is there a RegexSet and if so is it not empty?"

Or in fact it introduces a risk of different behavior when it is None vs Some(RegexSet::empty()), which I'd rather avoid. You could say, well, that's my problem to avoid. But it seems idiomatic in Rust to have an impl Default for everything that has a clearly-defined empty value?


        if let Some(examine_re) = &options.examine_functions {
            if !examine_re.is_empty() {
                mutants.retain(|m| examine_re.is_match(&m.format_as_error_message()));
            }
        }
        if let Some(exclude_re) = &options.exclude_functions {
            if !exclude_re.is_empty() {
                mutants.retain(|m| !exclude_re.is_match(&m.format_as_error_message()));
            }
        }

I had the same thoughts about whether there should be a default Regex and whether it should match everything or nothing, which gets a bit philosophical.

But for RegexSet it seems much easier, because as you say

  1. It is the same thing you get from passing a default vec or other iterable to the new constructor, i.e. empty.
  2. It already has a well-defined concept of being empty, literally under that name.
  3. It's described as a set and as a union of regexes and those all have an obvious zero identity, i.e. empty, without having to define a default for Regex.

(I think on the whole perhaps Regex::default could be the same as a regex compiled from "", i.e. a zero-length match. But we don't need to get into that here, and it does seem like a less safe default.)

sourcefrog avatar Sep 22 '22 00:09 sourcefrog