[darcs-devel] experiment: modular primitive patches and hunk move

Ganesh Sittampalam ganesh at earth.li
Sat May 22 19:41:57 UTC 2021


Hi,

I've been playing around with our types for primitive patches, with the
idea of making the types a bit more compositional and also figuring out
how to implement hunk move.

For hunk move, I'm particularly concerned about how to deal with all the
different cases in the commute rules: both the from and to sides of the
move need to be compared against paths and line numbers in the patch
they commute with and it feels like there would be an explosion of
different cases. Ben, I have a feeling you said you have already
prototyped this, if so I'd be interested to see what you came up with.

My other interest is in different uses for darcs patches. For example I
think it should be possible to build code review and conflict resolution
tools based around breaking down a diff into separate patches.

So far, my experiment does the following:

1) Change path handling to work one level at a time. Either a patch is
on the current filesystem object (a file/directory) or on a subdirectory
of the current directory.

2) Move operations are treated as Cut and then a Paste with a notional
intervening clipboard. This adds quite a lot of complexity but also
simplifies the side-condition checking.

3) Add/Remove operations are lifted up into a new intermediate level
alongside Cut/Paste, to separate them from patches that only touch the
content of a file.

4) HunkMove is introduced by adding CutHunk/PasteHunk at the content
level. This reuses the clipboard concept and I think it may justify the
extra complexity the clipboard introduces.

I've uploaded my code, the new types are here:

https://hub.darcs.net/ganesh/modular-20210519/browse/src/Darcs/Patch/Prim/V1/Core.hs#70

And the new commute code here:

https://hub.darcs.net/ganesh/modular-20210519/browse/src/Darcs/Patch/Prim/V1/Commute.hs#42

The commute code specifically relating to hunk move starts here:

https://hub.darcs.net/ganesh/modular-20210519/browse/src/Darcs/Patch/Prim/V1/Commute.hs#351

The hunk move code still has lots of bugs, shown up by QuickCheck, but
it gives a general idea of the concepts.

I'd also like to make it more generic/modular still: for example the
content type could probably be split up further, and made polymorphic on
the actual line content. At some point it might be interesting to add
patches that work on the characters of single lines or groups of lines,
such as changing indentation. The patches on directories could be
repurposed to operate on generic tree structures.

I doubt we'd want to actually use this refactoring for real. For one
thing handling paths one level at a time will probably be much less
efficient.

Also my new code has lots of "impossible" cases introduced by the
clipboard concept ("nestingError") - I tried to use types to rule them
out but was defeated by the type-checker.

I'm starting to think that for complicated patch types we should model
them in some properly dependently typed language like Idris or F*, and
then either use that model as a specification to test against, or just
transpose it directly into Haskell. That might also allow us to verify
that the commute rules themselves are correct.

Cheers,

Ganesh


More information about the darcs-devel mailing list