R

Russell O'Connor

r6.ca · Personal blog · on HN since 2009

Russell O'Connor is a Haskell programmer and formal methods researcher who writes about algorithms, compilers, Git, and Bitcoin.

What HN saysHN links his post showing Gauss-Jordan, Floyd-Warshall, and Kleene's algorithm are one general method. Commenters otherwise cite his posts without giving opinions.
40HN people shared it
22linked it in comments
19stories submitted
1.2Kstory points
7 months agolast shared
2009people per year2026

Most-shared posts

  1. 1
    A Very General Method of Computing Shortest Paths
    7 people · 5 points · first shared 2011 · 1 comments on HN
  2. 2
    It Is Never a Compiler Bug Until It Is
    6 people · 259 points · first shared 2020 · 132 comments on HN
  3. 3
    Confession of a Haskell Hacker
    4 people · 165 points · first shared 2012 · 124 comments on HN
  4. 4
    Do Not Play the Lottery Unless You Are a Millionaire
    4 people · 31 points · first shared 2009 · 18 comments on HN
  5. 5
    Git is Inconsistent
    3 people · 160 points · first shared 2011 · 79 comments on HN
  6. 6
    20060919T084800Z
    3 people · first shared 2017
  7. 7
    Why Is It Taking 20 Minutes to Mine This Bitcoin Block?
    2 people · 260 points · first shared 2018 · 113 comments on HN
  8. 8
  9. 9
  10. 10
    Thesis.pdf
    2 people · first shared 2021
  11. 11
    Goedel1
    2 people · first shared 2019
  12. 12
    Functor-Oriented Programming
    1 people · 179 points · first shared 2017 · 67 comments on HN
  13. 13
    Kelly Criterion (2007)
    1 people · 164 points · first shared 2018 · 96 comments on HN
  14. 14
    Object Oriented Programmer’s Productivity
    1 people · 9 points · first shared 2009 · 1 comments on HN
  15. 15
    On the Static Nature of Traversals
    1 people · 2 points · first shared 2024 · discussion on HN

What HN people wrote when they linked it

rssoconnor · 2022-03-30
Not only can you do that in NixOS, but you can even do something lighter weight and apply a patch to an existing package. This has the advantage that the patch often persists through software updates. For example, I used to patch OpenSSH to increase the minimum field size for DH key exchanges [1]. Eventually OpenSSH did update their minimum field sizes so I do not use this patch anymore. [1] https://r6.ca/blog/20150111T040537Z.html For those interested, patching OpenSSH in NixOS involves adding the following to one's system configuration: nixpkgs.config.packageOverrides = oldpkgs: { openssh = pkgs.lib.overrideDerivation oldpkgs.openssh (oldAttrs: { patches = oldAttrs.patches ++ [ ./openssh-dh-grp-min.patch ]; }); }; where openssh-dh-grp-min.patch is the patch file you want to apply.
chimeracoder · 2013-09-29
I've done a decent amount of work in both - I've written a compiler in OCaml and a few applications in Haskell. I do find Go to have the "best of both worlds" when it comes to the type system (ignoring all other features of the languages). As you know, one of the advantages of writing in dynamic languages like Ruby and Python is that you don't have to think much before writing down the first few lines of (working, runnable) code. This makes it really easy to sit down at a keyboard and bang out a prototype, or even a one-off utility script. With Haskell, I have to spend a lot of time thinking up-front about how to design my types, because the arrangement of the datatypes largely determines the functionality of your program. The upside is that, once you've sketched out what you need your types to look like in Haskell, the entire structure of your application has essentially been stubbed out - you simply need to fill in the gaps. This is really nice when making incredibly polymorphic functions - as has been pointed out, you can implement an entire Haskell library without understanding anything about the logic, operating solely off of the type annotations[0]. The downside is that it takes longer to get those first few lines of (working, runnable) code down. Maybe that's not a big loss, or maybe it is. But Go does provide a lot more type safety than any of C or Java (and certainly a lot more than any dynamic language than Ruby or Python). I'm a functional programmer at…
tel · 2013-05-25
We know some things for (a-d). For instance, a string is (in every case I've seen) a monoid, you can append to either end and there exists an "empty" string which turns appending into an identity. For (e) this may not be true if we want to treat the string as semantically equivalent to whatever its representing---you cannot always arbitrarily append represented objects. That said, a string is not that represented object unless there's an isomorphism. In Haskell types, you'd want to have a `String -> Maybe a` function to capture failure-to-translate. This case includes things like `SQLSanitize`. Also HTML header parsing whenever the headers have an interpretation in the current level of the system. Note also that this value of (e) does not depend upon a representation of strings as any kind of character-based thing. You can make a monoidal representation of a regular expression from a star-semiring combinator set (and see http://r6.ca/blog/20110808T035622Z.html for a great example). The remaining semantic troubles seem to be around ideas of mapping or folding over a string. Length depends on this representation---do I want character length or byte length?---as do functions like `toUppercase`. And then there's the entire encoding/byte-representation business. So they should perhaps be instances of an abstract class of "Monoid" plus a mixin specializing the kind of "character" representation. Or, the outside-in method of Haskell's typeclasses where String,…
aweinstock · 2024-03-05
The post "A Very General Method of Computing Shortest Paths" (https://r6.ca/blog/20110808T035622Z.html) shows that the Gauss-Jordan algorithm for solving matrix equations, the Floyd-Warshall algorithm for all-pairs shortest paths, and Kleene's algorithm for converting DFAs to regular expressions, are all the same algorithm on matrices of elements from a star-semiring.
throwaway81523 · 2023-02-23
You want to read about the Kelly criterion for that. Russ O'Connor has a good article explaining why the lottery is a bad deal on that basis: http://r6.ca/blog/20090522T015739Z.html
yjftsjthsd-h · 2021-11-08
Reminds me of: "It Is Never a Compiler Bug Until It Is" (https://r6.ca/blog/20200929T023701Z.html , https://news.ycombinator.com/item?id=24636326). The bottom of the modern stack is really reliable, until it isn't;)
nullc · 2021-09-21
Roconnor explains his position, you do not. Roconnor is a published expert in this domain, in fact his PHD thesis ( https://r6.ca/thesis.pdf ) was on formalizing and machine proving Gödel's incompleteness theorem. Instead, without justification or argument, you would like us to take the word of a person who failed the only theory of computation class he's taken and has been found by multiple courts to be an unreliable witness, a liar, and a forger-- a person for who has collected astounding sums on money on the promise of someday sharing some storied treasure which he-- as he's recently been forced to admit in court-- has no access to. I see how your logic works, and I expect that most readers of this thread will as well.
eru · 2020-09-02
> If you need arbitrary precision because of the pathological features of a particular family of graph (expander graphs, say), and the scaling of the needed precision links directly to aspects of that graph pathology, this is really telling you that the eigenvector computation is not the most natural “computation basis” to approach this phenomenon — and some explicitly discrete algorithm would make this latent complexity relationship manifest. Or perhaps you just need to perform your eigenvector computation in a more hospitable ring or field? To give an example of the flavour: many graph computations are more natural when performed on their adjacency matrix over tropical semi-rings. First and foremost shortest path computations. See eg http://r6.ca/blog/20110808T035622Z.html or http://stedolan.net/research/semirings.pdf
Kednicma · 2020-08-07
It's a book! I was expecting a short paper along the lines of [0] or [1] but this is going to take a while to evaluate. Nonetheless I like the surface-level presentation and it seems like the author takes the time to carefully explain each concept in detail. [0] http://tac.mta.ca/tac/reprints/articles/15/tr15.pdf [1] http://r6.ca/Goedel/goedel1.html
brzozowski · 2020-07-13
Related article by Russell O’Connor about copyright assignment I recently stumbled onto: http://r6.ca/blog/20110930T012533Z.html
Mathnerd314 · 2019-08-14
It's valid Haskell 98 with a type constructor: http://r6.ca/blog/20060919T084800Z.html. But in GHC I think the first code snippet without NOINLINE still crashes, it's a perma-bug: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/bugs.h… Some type systems do support equi-recursive types without the type constructor, e.g. Whiley (http://whiley.org/2013/04/21/iso-recursive-versus-equi-recursive-types… Maybe there you could implement Y without a type signature and have the recursive type inferred. The main problem is speed. Using the Y combinator is going to mess up whatever code flow analysis the compiler has, unless it's using some cutting edge optimization research that I haven't been able to find.
gylterud · 2019-06-10
However, even with positive expectation value, you should not always play. One should first check the Kelly criterion, which is well explained Russel O’Connor’s blog post: “Do Not Play the Lottery Unless You Are a Millionaire” http://r6.ca/blog/20090522T015739Z.html
tome · 2017-11-23
> 1. FP programming languages are not really Church’s lambda calculus, and the Y combinator in them is implicit. You cannot define a Y combinator in a typed LC. Well actually ... http://r6.ca/blog/20060919T084800Z.html But that's besides the point. Haskell already has a perfectly good recursion combinator called `fix`.
tuukkah · 2012-05-08
Just found out about this part of the U.S. law in a discussion on how researchers can free the papers that academic publishers keep behind paywalls: http://r6.ca/blog/20120505T173911Z.html EDIT: Also here regarding Oracle vs Google: http://news.ycombinator.com/item?id=3942094
Paracompact · 2025-07-31
Nope! Not a troll question. At the end of the day, we're human beings interacting with a bunch of electrified rocks. There will always be a layer of subjectivity and expertise involved in translating informal (or perhaps even unknown) desires into formal specs. It gets even worse when you are designing software that needs to take into account the underlying behavior of hardware; you wouldn't program an autopilot for a jumbo jet whose certification only exists in the context of some simplified formal model for how computers work, do you? But I'm catastrophizing. If you think going through the definitions of a spec are painstaking and require expert insight to get right, it is miniscule compared to e.g. auditing every line of a codebase written in an imperative language. And not only that, to even get close to the same correctness guarantees of e.g. a formally verified pipeline through CompCert, you would have to audit every line of the codebases of every compiler that touches your code (https://r6.ca/blog/20200929T023701Z.html "It Is Never a Compiler Bug Until It Is"), together with analysis of the underlying hardware models. All this to say, technology is more complicated than traditional programmers exposed only to high-level languages might be led to believe. That complication can only be reduced, consolidated, or blackboxed so much.
segfaultbuserr · 2020-10-09
The original secp256k1 developer Russell O’Connor who was hit by the bug (was on HN [0]) [1] said he rebuilt every package in his system after the bug was identified, and found only 10 lines of code that were miscompiled. Also, note that the bug was found during an attempt to add more test cases, pre-existing code in secp256k1 was not affected. > Three lines are tests. All of the lines could be rewritten as a comparison to 0. None of the lines looked that serious. I am not sure which one is the worse: the reduced message integrity code(?) from some ARCFOUR implementation or the something something from an ATM driver? Two unusual conditions are needed to trigger it... > * at least one of the compared byte arrays is constant and has a zero byte in position 0, 1, 2, or 3, and > * the result of the memcmp isn't immediately used in a "== 0" or "!= 0" test (or equivalently "if(memcmp(...))" or "if(!memcmp(...))"). > In particular the second condition makes this bug pretty rare and explains why it's mostly hit in non-inlined memcmp wrappers. (But in our case we hit it with a "<" comparison. ) Looks like a critical bug, but doesn't look like a conspiracy. [0] https://news.ycombinator.com/item?id=24636326 [1] http://r6.ca/blog/20200929T023701Z.html
lidHanteyk · 2019-12-30
For fuck's sake. > For instance, it's impossible to write an executable program in Java that adds a string to a number. Wrong [0] and misleading and not a reasonable summary of type-driven development. The article goes rapidly downhill from there. It tastes like an undergrad who has just learned about the very basics of things and is still trying to figure out how to put them all together. > So it is possible to statically verify that a function always returns the square of its input, it just needs a proof (aka its type). This is not sufficiently convincing. What exactly was that type, and which language was it written in? The type "int -> int" is not at all enough. This sort of handwaving logic seems to come up constantly with folks new to type theory. And each time it comes up, it seems that a massive argument must happen [1] in which folks who actually understand type theory have to remind folks that no, type systems do not automatically save us. Here are two analogies in the article. "I'm lying" is a reference to a famous paradox [2], and the barber story is a truncated part of an older set of stories told by Russell, Gardner, Smullyan, and others [3]. All fine and well. However, they then try to claim that types somehow fix the underlying paradoxes, but of course, they don't. This is because the underlying cause of the paradoxes is of course Gödel's first incompleteness, which works even in statically-typed environments [4]. Worse, the article author makes it sound…
nicklaf · 2019-06-11
I am still learning this stuff (and have only had undergrad abstract algebra), so thank you for the context and motivation. As it happens, today I was thinking about semirings, and how to apply them to discrete event systems[1][2], and was fascinated to see that both algebraic geometers (Alexander Grothendieck) and computer scientists (Robin Milner) were doing[3] some of the same[4] sorts of tricks to transfer algebraic structures (like rings) over to settings lacking an inverse (like semirings)--rather than take the direct approach (as you mentioned in your lattice example): There are many times in mathematics where some class of objects has a nice additive structure, except that one can’t always invert elements. One approach is to say, “oh well,” and develop the theory of monoids; another,which we’ll discuss today, adds in formal inverses, in effect pretending that they exist, and uses them to recover something useful. [1] https://www.cl.cam.ac.uk/%7Esd601/papers/semirings.pdf [2] http://r6.ca/blog/20110808T035622Z.html [3] https://web.ma.utexas.edu/users/a.debray/lecture_notes/sophex_11_13.pd… [4] https://old.reddit.com/r/haskell/comments/2d8q24/additivemultiplicativ…
hyperpape · 2017-10-11
Low level stuff, at least in public: http://r6.ca/code.html
aseipp · 2017-02-14
FWIW, this is traditionally quite possible with Darcs. I sort of misformulated in my original post; it's not like it just gives up and you're at square one. The workflow IIRC was basically the same as Git: it'll throw its hands up and you make a new commit to fix everything. So that isn't really a problem or any different. Note that Darcs 1 did have the exponential merge case on top of this, however, which was pretty unfortunate (and really a byproduct of the design of the change format, among other things). In all honesty, given years of experience with Git, and fondly using Darcs as my first version control system: I still think merges are absolutely the one thing it beats Git at, hands down. When it works and it does its job, it always is correct. When it doesn't, you can bail it out. Not much different, but the "always is correct" and dependencies-being-implicit is what makes it good. Darcs could have saved me at least dozens of hours of hair pulling when doing STABLE merges I estimate... Git's still good. I wish it could do that, though... Your note about git is interesting. In fact, Git is, in at least some cases, more magical than other VCSs in the merge department. You might just not be aware of it due to being so familiar. When I say "Darcs always gets the merge correct", I don't just mean it literally finishes with exit code 0, but also that the semantic model is, in some sense, more 'correct' or 'intuitive': http://r6.ca/blog/20110416T204742Z.html Darcs (and…

Keyboard shortcuts

/Search
j kNext / previous blog
EnterOpen selected blog
vVisit the blog site
fFollow / unfollow
lSwitch grid / list view
dSwitch dark mode
g hHome
g pTop posts
g tTopics
g fFollowing
g lLiked
g yHistory
g qFAQ
EscBack / close