ydiff is a language-aware tool for comparing programs. It supports multiple languages and has an extensible design. It is not yet ready for general release, although it is already an indispensible tool to me.
ydiff is an open source project. You can follow its development on github: yinwang0/ydiff or get its source code from there. If you want to know more about it, welcome to read on and play with the interactive demos provided at the end of this page.
We very often want to know how our code is modified. This is normally done by using the diff program. While effective for finding differences between close revisions, the result from diff can be very hard to read for revisions over a long time span. The worst case is when the code is massively rearranged or refactored, where diff considers every line to have been changed.
ydiff can help in this kind of situation. Different from line-based or character-based diff, ydiff is "language-based". It parses the programs and then performs structural comparison on the parse trees. In addition to the usual functionalities of diff, it has the following properties:
These properties make ydiff helpful for understanding changes. It may also be possibly used for detecting plagiarism in programming classes or copyright infringement of code.
I wanted to use the name "λdiff", but having noticed how troublesome it is to type it from the command line, I decided to flip its first letter upside down.
Currently ydiff supports the following languages:
I will be adding more languages.
GPL v3
Yin Wang (yinwang0@gmail.com)
You are welcome to have a look at the demos. They are fun to play with. The demos are interactive HTML files. All program structures are in framed nodes, whose colors mean:
The left and right windows are always locked in their relative position. A mouse click on changed, moved or unchanged nodes will highlight the matched nodes and scroll the other window to match. After that, the windows will be locked into their new relative position for browsing.
Okay, here are the demos:
Comparison of the
original miniKanren
from Professor Dan Friendman and the version I modified in order to
support condc, a "negation operator", which fascinated me for
quite some time. Pay attention to
unify, whose major part is moved
into unify-good, the righteous opponent
of unify-evil.
Comparison of two versions (v20 and v22) of Taylor Campbell's paredit-mode, a wonderful tool for editing Lisp programs.
Trying to find a bug in an optimizing pass of my Scheme compiler by comparing the IRs.
Comparison of two implementations of a small list library that I
wrote, which implements Lisp-style lists. The first implementation
uses recursive procedures while the second uses Python's generator
syntax and is iterative. Pay some attention to append,
whose code is moved inside another function appendAll.
Comparison between two major revisions of the UI code of ydiff itself.
There are two demos for C++. The first demo compares two versions of the d8 Javascript debugger from the V8 project (v3404 from 2009 and the current v8424). The second demo compares V8's simulators for two different processors (MIPS and ARM).
The d8 demo is especially interesting because by clicking on the
lines of the method Shell::Initialize in the old version,
it can be clearly observed that its body has been distributed into
several procedures in the new version:
Shell::Initialize Shell::CreateGlobalTemplate Shell::RenewEvaluationContext Shell::InstallUtilityScript
Also the major part of Shell::Main is moved into the
helper Shell::RunMain.