Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Needlessly exponential pattern-matching #259

Open
quasicomputational opened this issue Mar 27, 2020 · 1 comment
Open

Needlessly exponential pattern-matching #259

quasicomputational opened this issue Mar 27, 2020 · 1 comment

Comments

@quasicomputational
Copy link
Collaborator

mkResult in Runner.Example is the heart of doctest: it checks the actual output against the expected pattern, which can include wildcards both within a line and across lines.

Here's how wildcard matching is implemented currently:

chunksMatch zs@(WildCardChunk : xs) (_:ys) =
let resWithoutWC = xs `chunksMatch` ys in
let resWithWC = zs `chunksMatch` ys in
let res = longerMatch resWithoutWC resWithWC in
prependWildcard res

and

matches zs@(WildCardLine : xs) us@(_ : ys) =
let matchWithoutWC = xs `matches` us in
let matchWithWC = zs `matches` ys in
matchWithoutWC `matchMax` (incLineNo matchWithWC)

Note that they'll try both branches in isolation, leading to an exponential running time on pathological input. This has been made slightly worse by #249 wanting to go down both branches to find the best place to show the difference, but it was there before.

In most cases this is pretty un-noticeable to users, who'll tend to use tame patterns, but it's currently biting me in running the test suite where QuickCheck generates some real monsters.

Since the patterns are a regular language, mkResult could be re-implemented to use finite automata instead, which should bring a significant speed-up on pathological input.

@amigalemming
Copy link

Can you recommend a Haskell-only regular-expression matching library? I think about implementing your suggestion in doctest-extract.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants