Hacker News new | past | comments | ask | show | jobs | submit | mookid11's comments login

you might like diffr (https://github.com/mookid/diffr) (disclaimer: my project)

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.


Matija Pretnar about the eff programming language and mathematical foundations for Effect Handlers.


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?)

[0]: https://github.com/mookid/diffr


Many of your concerns could be alleviated by using Tree-Sitter. (https://tree-sitter.github.io/tree-sitter/)


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.


Sort of related: as I never made diff-highlight work correctly on Windows, I wrote diffr[0] which goes a little bit behond what diff-highlight does.

[0]: https://github.com/mookid/diffr


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.


> For example, you'd not get far in Rust without Result<>, Option<> or Future<> which are all make use of delayed resolution for their value.

Certainly not for Result<> or Option<>.


It depends if you enjoy NullPointerExceptions.


> Haskell has some nice things going for it. Its syntax is cleaner than OCaml's, for example.

While I find the ocaml syntax very far from perfect, the whitespace sensitivity of Haskell makes it immediately worse. What a silly design.


IMHO, it's not so much that as the ASCII operator galore. $, <*>, the horrible lambda syntax... Sometimes it looks an opinionated Perl.


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 doesn't really have the problems that are commonly associated with operator overloading.

Nobody said it did. People said that it has its own brand of problems with operators looking something like >>+@*<>> peppering your code.


lol i wonder if you work on my team


>Also, you can just define as many new operators as you like.

this is exactly the problem


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.


Haskell doesn't have overloading at all, either of operators nor of non-operator identifiers, so I guess you mean something else.

Do you mean user-defined operators, or do you mean operators whose type has a typeclass context?


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.


How does the whitespace sensitivity make it immediately worse?


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.


By no means. Haskell's semantics are extremely simple. Python's are complicated.


Youmeanwhitespaceisbad?C64basicrules!


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.


Interesting how the author avoids to mention OCaml's (far from perfect, but still) object system.


And how F# was made by OCamlers.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: