Hacker News new | past | comments | ask | show | jobs | submit login

That's a pretty cynical take. I think a more profound problem is that formal specifications for software are fairly intractable.

For a bridge, you specify that it needs to withstand specific static and dynamic loads, plus several other things like that. Once you have the a handful of formulas sorted out, you can design thousands of bridges the same way; most of the implementation details, such as which color they paint it, don't matter much. I'm not talking out of my butt: I had a car bridge built and still have all the engineering plans. There's a lot of knowledge that goes into making them, but the resulting specification is surprisingly small.

Now try to formally specify a browser. The complexity of the specification will probably rival the complexity of implementation itself. You can break it into small state machines and work with that, but if you prove the correctness of 10,000 state machines, what did you actually prove about the big picture?

If you want to eliminate security issues, what does it even mean that a browser is secure? It runs code from the internet. It reads and writes files. I talks directly to hardware. We have some intuitive sense of what it's supposed and not supposed to do, but now write this down as math...




My experience with formal specifications was that our specification ended up being more complex than the code itself.

This is a tricky problem, because your specifications can and usually does have bugs. I once measured this on a project I worked on and found that it accounted for up to ~60% of all incoming bugs - that is, 60% of bugs were due to misunderstandings or miscommunications involving a spec of some kind.

The added complexity of formal verification languages creates an opening for specification bugs to creep in. The net effect was that we might have had 0 code bugs via this automatic proving system but the number of bugs in the specification actually went up.

I'm been deeply cynical about formal verification ever since. I'm not even of the opinion that it's "maybe not good for us, but good for building code for rocket ships". I think it might be actually bad at that too.

I'm bullish on more sophisticated type systems and more sophisticated testing, but not formal verification.


>This is a tricky problem, because your specifications can and usually does have bugs. I once measured this on a project I worked on and found that it accounted for up to ~60% of all incoming bugs - that is, 60% of bugs were due to misunderstandings or miscommunications involving a spec of some kind.

Well, OK, but the reason you have "bugs" in your specifications is usually that the English-language (or whatever you have) informal requirements documentation is imprecise, ambiguous or contradictory.

At least with a formal specification, you shouldn't have that problem.


Using existing techniques, the formal specification is almost always multiple times larger than a formally correct implementation. The accompanying proof is then tens to hundreds of times larger than the specification assuming one is even constructible at all (which is basically only true for small programs).

Luckily, a sound proof verification engine is feasible, so you are unlikely to have a "proof error" despite the proof "implementation" being so much larger. But, the fact that the specification is much larger than the implementation means there is more room for specification errors than implementation errors. The reason why you might still want a formal specification even if it is larger is that you can prove it and you can formally reason about the specification, goals, and interactions. It remains to be seen if we can invent a way to consistently make a formal specification simpler than the implementation which would be the holy grail as there would be no downsides.


There are *lots* of potential reasons for specification bugs. Informally delivered requirements is just one of them and I'm not sure it is even the most common.

Formal specification languages are more likely to have specification bugs despite being precise and unambiguous for the same reason programming languages have bugs despite being precise and unambiguous: they are complicated and extremely expressive languages which means a larger scope for mistakes, misunderstandings and accidental misinterpretation.

Were formal specification languages straightforward and simple the scope for misunderstanding and misinterpretation would decline, but so would the power to "prove" the code is free of bugs.


More likely than what? Informal specifications?

My primary experience with formal specifications is as part of a literate specification, where you would have a rigorous English-language explanation interspersed with the formal specification (e.g. Z schemata).

A reader can look at the formal specification and the English and decide whether they think they mean the same thing; experience suggests that most engineers or people with STEM-type backgrounds need no more than a few days of training to be able to read Z (even if they can't write it).

The document as a whole can be type-checked, which is a lightweight way to check for the most egregious kinds of errors.


More likely than semi formal.

The normal way I get specs is not via a drunk phone call (thank god) but via jira tickets that have been discussed and list concrete examples. I think this is pretty normal for many people.

I received training in Z and I balk at the idea of reading it. Though you dont seem to believe it, I can well believe that the gap between the English language spec and the formal spec is easily desynchronized and infested with bugs.


This is the thing that I'm finding difficulty with - the formal specification isn't an alternative to an informal specification; it should go along with one.

Specification "by example" is, in my experience, almost guaranteed to result in missed cases or unspecified behaviors in uncommon situations.


>This is the thing that I'm finding difficulty with - the formal specification isn't an alternative to an informal specification; it should go along with one.

Why are you finding difficulty with that? Not having formal verification is an alternative to having a formal verification.

There ought to be a cost/benefit analysis applied to the tool - i.e. does the cost of writing and maintaining the formal specification pay for itself in terms of bugs caught. Does it have the potential to create new kinds of bugs? (I would argue yes).

The common belief is that it does bring value for certain types of code (rocket ships, maybe pacemakers? etc.), however very few people actually use it because for most applications a certain level of bugginess is perfectly fine. As a result, very few people actually have experience with it.

>Specification "by example" is, in my experience, almost guaranteed to result in missed cases or unspecified behaviors in uncommon situations.

Specification by example does mean missed cases, yes, but the missed cases will get caught by manual testers involved in the process of writing the examples, programmers while implementing the code or fuzz testing.

The dysfunctions I tend to see aren't edge case scenarios being missed altogether, but:

* Not involving programmers / testers who would spot the edge cases in the process of writing the examples. This is typically an organizational dysfunction.

* The programmer decides themselves what the correct behavior should be during edge cases without consulting the stakeholders.

* The PO/PM/Developers make poor decisions about overall architecture or intended edge case behavior. A large part of good system design involves constraining the number of inputs to a system so that the number of potential scenarios doesn't explode unmanageably.

The question I think formal verification has to answer is - does it actually bring any value if you are already doing all of those things or is it more of a performative ritual to ward off the bug spirits?


> your specifications can and usually does have bugs

One cool thing about formal verification is that you can not only prove things about your code, but you can prove things about the specification itself (with some approaches, at least). This includes proving arbitrary properties, proving the presence of bugs, proving the absence of bugs and in some cases, even proving full correctness of the specification.

> I'm bullish on more sophisticated type systems [...] but not formal verification.

I don't know what kind of formal verification framework you used that left you with this conclusion, but the more sophisticated is your type system, the closer you are to doing formal verification.


Z notation is the framework which left me with this conclusion. It was allegedly named this by its founder because it is "the ultimate" language. I thought it was terrible.

I've used plenty of type systems, and they have all provided a means to annotate the code and then prove certain properties about the code, but I have never in my life seen a type system which let me define a whole specification as formal verification does.

I have also seen type systems go waaaay overboard. They ended up inhibiting development velocity because they were so intent on forcing the programmer prove of the code properties that actually didn't need to be proven.

In general, I think type systems that try to strongly limit the scope of the properties they are trying to prove and apply a cost/benefit trade off to the value of the proven properties and the costs of the annotation work best.


First, did you (or anyone) write up the results from your measurement? That sounds like empirical data on a subject where I have never heard of their being data, so it would be really useful to capture it.

Second:

> The net effect was that we might have had 0 code bugs via this automatic proving system but the number of bugs in the specification actually went up.

Are you saying that this is part of what you measured? Or are you merely saying that this is hypothetically a way things could work out?


>Are you saying that this is part of what you measured? Or are you merely saying that this is hypothetically a way things could work out?

I'm saying that, anecdotally, when I tried it I had more bugs thanks to formal verification because bugs crept into the spec. It was very hard to tell that those bugs were present because the spec was very, very complicated.

I'm not denying that it can catch bugs at all, just that a successful "proof" didn't mean a lack of bugs and that I personally found it to be a relatively inefficient method of catching bugs (or demonstrating their nonexistence).


>That sounds like empirical data on a subject where I have never heard of their being data

c.f.

https://userweb.cs.txstate.edu/~rp31/papers/KingHammondChapm...


Formal proof of correctness vs. manually created tests.

The comparison should be formal proof of correctness vs. fuzzing using the formal specification as a source of properties to be tested.


Fuzzing is a statistical technique that isn't ever going to give you a reassurance that a problem doesn't exist. It's great at giving you counterexamples, so fuzzing is great for discovering vulnerabilities, but unless you're fuzzing your program's entire state-space (which is absolutely impossible for even relatively small programs) then you're not comparing like with like.


>Fuzzing is a statistical technique that isn't ever going to give you a reassurance that a problem doesn't exist.

Formal verification doesn't prove that bugs don't exist either, thanks to the aforementioned "bugs in the spec" scenario.


So? The paper compared formal techniques vs. testing. Why is that suddenly not appropriate if the testing is fuzzing?


Browsers have been grown, not designed. The competitive pressures exuded on browsers to render ill-specified things and hacks has resulted in something essentially where what it does is what it does. That's the case with a lot of software,because we made the choice as a community of programmers to not formally verify the things that we build. Thunk of the origin of the blink tag [1]. We decided to be hackers, and doers, not thinkers.

Just as testing changes the way you structure your software, designing via formal methods changes the code that you produce as well, and it will attract a different set of people than traditional software dev, just as architecture attracts a different set of people than carpentry.

1. https://danq.me/2020/11/11/blink-and-marquee/#:~:text=Invent....


A browser is possibly the most difficult application to formally specify. 99.somemorenines% of software has less complex specifications.

The formal specification for something like Redis is likely much more akin to your car bridge spec. And to continue your analogy, I imagine the specifications for big bridges (Golden Gate, etc) are much more thorough than the ones you built.


A browser is one of the most consequential attack surfaces in the lives of billions of people. Redis isn't. Having proofs where said proofs don't matter much in the first place is not a particularly good use of our time. And FWIW, the correctness specs for Redis would be pretty intractable too.


Type systems are "formal specifications for software" if perhaps in a fairly lightweight sense, and they work quite well. If you write a web browser in a strongly checked language such as Rust (the Servo folks are working on this, and shipping parts of their work in Firefox) you can ensure that it's not going to break memory safety, which is a start.




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: