First of all, this is why people should stop adding stupid features to regular expressions. A sane regular expression implementation has no pathological cases. DFA generation can be done in O(n^2) from memory (in the absolute worst case O(n) is average), and matching can't be worse than O(m) or similar (n is the size of the regex and m the size of the string). When you add features like back references and recursive…
You don't need to throw out your favorite regex features—backreferences aren't stupid, they're useful and usually harmless! Rather, a good regex engine should start with recursive backtracking (ideally JIT'd) and fall back to the Thompson NFA if the regex supports it and the recursive backtracking approach is taking too long. Think of it like the adaptive sorting algorithms that switch between insertion sort and quic…
How I fixed a bug in Atom
171–180 of 189 posts
Re: How I fixed a bug in Atom
#172I liked this article a lot. A programmer found a bug in something he uses every day, and learned enough to fix it. I think articles like this are very useful to beginner/intermediate developers. Everyone in software says "write open source code", "make pull requests to code you use" etc, but there's a very big gap between knowing how to program and knowing how to track down, fix, and submit a PR for a bug in a progra…
Maybe I should write up a blog post like this one..
Re: How I fixed a bug in Atom
#173Earlier quoted context omitted.
"I don't always want to spend insane amounts of time writing full AST parsers." This is an effect of the language, not the problem space. Backtracking REs make it very easy to write bad code, and then most languages make writing the parsing code hard. If you're in a language that makes parsing code easier, like Haskell, then the tradeoff isn't anywhere near so bad. I don't mention Haskell just because it's the trendy…
Haskell is, in fact, a really good way to write parser code. That's the main thing I use Haskell for. But how are you suggesting that Haskell could solve the problem of letting CoffeeScript plugins express which text they should apply to in a CoffeeScript text editor?
He's suggesting that the correct solution (recursive descent parser) is not inherently hard, but CoffeeScript makes it hard enough that people reach for less good approaches.
Re: How I fixed a bug in Atom
#174Could be avoided if the editor had a full AST of the code instead of using regular expressions to try to make sense of it.
The syntax will be broken 99% of the time and making a parser that recovers gracefully under any circumstance is very hard. You could make an editor that only allows valid programs but that opens up a lot of UI problems, it was tried many times and it never took off in practice.
Re: How I fixed a bug in Atom
#175First of all, this is why people should stop adding stupid features to regular expressions. A sane regular expression implementation has no pathological cases. DFA generation can be done in O(n^2) from memory (in the absolute worst case O(n) is average), and matching can't be worse than O(m) or similar (n is the size of the regex and m the size of the string). When you add features like back references and recursive…
> The conversion from DFA to NFA [...] I believe you mean NFA to DFA. > [...] would require O(n^2) in that case I believe you mean O(2^n). https://en.wikipedia.org/wiki/Powerset_construction#Complexi...
> I believe you mean NFA to DFA.
Yes, you're right. Whoops :P.
> > [...] would require O(n^2) in that case
> I believe you mean O(2^n).
Ah yes, I forgot that you could chain epsilon edges. Fair enough.
Re: How I fixed a bug in Atom
#176> Having very little to go on, I began the search by searching the whole codebase for the word “newline”. Is this really how people troubleshoot JS issues? In 2016?
I don't know javascript beyond the most basic aspects, what would you have suggested here.
Re: How I fixed a bug in Atom
#177Isn't arbitrarily-long nesting or matching any sort of palindrome, where you count up and down, the classic case of something you should never do with a regex, because they're finite automata? People don't build parsers because of masochism, but because regular expressions are provably insufficient to capture things like nesting. You need to go at least one level up on the Chomsky hierarchy[1] to pushdown automata fo…
Yes, but features like backtracking and backreferences (or recursive referencing) make regex implementations non-regular regular expressions. That comes with a whole heap of issues (pathologically exponential complexities in any circumstance where backtracking is inolved).
Re: How I fixed a bug in Atom
#178Earlier quoted context omitted.
> vim and emacs are friendly and welcoming to people who already know them; new users in 2016 have some weird expectations due to growing up using insufficiently-powerful UIs, which means that they have quite a learning curve when picking up a powerful UI. Having first used both vi and emacs (and other text-mode - and even line-mode -- editors), though only casually then, I disagree; vi and emacs are, like almost any…
> So, there really was no trade off for the power vi and emacs offered (less powerful alternatives of the time were still just as inaccessible), where now there is. There's simply nothing out there as good as emacs. Nothing. Eclipse, IntelliJ, Atom, SublimeText, all those pale in comparison. vim has its positive points (it's an excellent way for a human to edit line-oriented text), but ultimately it too falls down in…
I think the only thing that Vim doesn't do that it should is actually use a proper language for scripting. Emacs has elisp, but Vim has VimScript which is a horribly stunted langauge.
Aside from that, I much prefer vim to emacs. Just because everything is mode-based, and the keybindings don't require 10 hands to do anything.
Re: How I fixed a bug in Atom
#179In general, when you are working on a problem and you think "let me use a regex for that" and then you come up with ^\s*[^\s()}]+(? [^()]*\((?:\g |[^()]*)\)[^()]*)*[^()]*\)[,]?$ to solve your problem, then you have IMHO come across a problem which you should not be solving using regular expressions. Case in point is counting and balancing parentheses which is very easily done using a single loop over the string in qu…
The worst part is that as soon as he mentioned regular expressions I knew exactly what the problem was. Regexes are powerful and useful but also dangerous. People who don't thoroughly understand them and try to get fancy often run into problems like this. In general you shouldn't be using them to parse a computer language anyway, it is something you should be using a tokenizer/parser for.
Re: How I fixed a bug in Atom
#180Earlier quoted context omitted.
Sometimes I feel like the difference between a junior, intermediate, and senior developers is that the junior hasn't yet figured out how to use regexps, the intermediate dev has, and the senior dev has figured out not to. I kid, but...really. The number of times I've seen people burnt by non-trivial regexps in production code is absurd. "Oh, I need to mangle this CSV that's in the wrong format"? Sure, write a one-off…
The famous "Gruber URL regexp", before an update in 2014, would run in exponential time given some URLs that contained parens. I noticed this when a web app I worked on froze on certain pages. Runaway regexp matching is one of the easiest ways to really lock a JavaScript thread.