Live data from Hacker News

How I fixed a bug in Atom

davidvgalbraith.com

171–180 of 189 posts

Re: How I fixed a bug in Atom

#171
post #10

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…

Do you know if any major regex implementations use the adaptive approach you're suggesting?

Re: How I fixed a bug in Atom

#172

I 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…

I agree. I was recently working with an npm package that wasn't behaving as expected. After some debugging on my end, I was convinced I was using the library as intended. So I started digging through the source code, wrote a few console.log()s, and found the issue. The check for a property in the code didn't match the property name in the README. A simple issue to fix but one that seems much more attainable if you know how someone worked their way to that point. A few years ago and I doubt I would have taken the time to dig.

Maybe I should write up a blog post like this one..

Re: How I fixed a bug in Atom

#173
post #135
post #98

Earlier 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 not suggesting that.

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

#174
post #22

Could 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.

Not just broken, but broken and changing. Efficiently updating an AST as the user types, especially when their changes could trigger dramatic alterations to the structure of the tree (e.g., typing /*) is a very hard problem. A responsive editor is pretty much always going to have to take some shortcuts.

Re: How I fixed a bug in Atom

#175
post #10

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…

> 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...

> > The conversion from DFA to NFA [...]

> 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
post #77

> 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.

Start debugger, cause 'freeze' to happen, pause debugger, look at call stack. I touch JavaScript as little as possible, but that's what I would do in any decent language.

Re: How I fixed a bug in Atom

#177

Isn'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…

> Isn'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?

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

#178
post #147

Earlier 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…

> 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 the general case

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

#179
post #110

In 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.

Hmm, if I remember right, on our compiler course we wre taught to build tokenizer with regexpes. As far as I unrestand, it is quite valid tool for that.

Re: How I fixed a bug in Atom

#180
post #80
post #45

Earlier 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.

I was also hit by this one in my pet IRC bot. :) URL matching would fail (occasionally) and the whole bot would freeze up. :<
Post reply on HN