I was about to make the same recommendation! I tried delta and difftastic and both were too much for me, so I've been using diffr as my git diff program for the past few years. It's delightful, thanks for making it.
Very nice, I've been looking for something like this since completing a port of DiffMatchPatch. I'll going to give it a spin right away, thanks for sharing your hard work!
As a bit of feedback, you might wish to put a section showing how to make a git alias for diffr, to complement the section on how to install it as the default. I know how to do this already, because I use delta and dft depending on what I need to see, but it would be useful to others to have a copy-paste solution handy.
I wrote diffr [0] for that purpose; it serves me well, especially if your team makes code with long lines.
In my opinion, a simple approach that does NOT make any parsing is more efficient (what about bugs in your parser? code with syntax errors? also, how fast would the parser be?)
Tree-sitter is great, but I find it could do a better job with broken code. This is particularly important when parsing things like C or C++ where the preprocessor makes it likely that unpreprocessed code can't be parsed anyway.
The point is to share intermediate state of your data structure without headache.
For instance, if you write an interpreter, representing variable bindings with a functional map allows to reason about scope super easily; when you change scope, you just create a new map with the new variable bindings, and when the scope ends you just get back the map at the scope beginning which is still valid.
With a stateful hashtable, you need to undo the changes you did in you scope; the value of the table when opening the scope that you want to get back to is gone forever. Now it ties you program to a certain execution order. One way to see that is that if you want to collect environment to each scope in some data structure for some reason, you need to make deep copies everywhere.
I don't know if you've worked with a production Haskell code base but it cannot be over stated what a poor decision operator overloading is. if they got rid of that it would immediately make Haskell an order of magnitude more practical
Haskell doesn't really have the problems that are commonly associated with operator overloading.
Haskell does have type classes, which do allow overloading, even of operators, but the type class uniquely determines the type of the operator - and there can be only one definition of any operator in scope.
Also, you can just define as many new operators as you like.
For these reasons, you can't have the madness of operator<< in C++, or whatever it is that Perl does with the same operator doing 5 completely different things depending on context.
Haskell for hobby programming coupled with professional Perl experience gave me enough idea of what creative programmers could come up with in terms of ASCII art.
If find these kind of comments really interesting, because for me Haskell's witespace-sensitivity immediately makes it a much better language! (I feel the same about Python).
It's interesting because (presumably) reasonable people really disagree on these issues.
Unless experienced, you have no clue how a piece of code will be parsed. With ocaml, where is very little ambiguity; and indentation tools can take care of proper formatting, you only need to break lines.
And it can be pretty bad with haskell, which has complex semantics compared to, say, python.
With whitespace sensitive syntax, I feel like in the dark age of manual indentation.
To allow IEEE compliant float with tagged pointers.
However, note that floats are not boxed in the OCaml's arrays. Boxing floats is a pain because it makes the price of defining subroutines taking float arguments high.
reply