
Software Foundations by Benjamin Pierce et al. - nextos
http://www.cis.upenn.edu/~bcpierce/sf/current/index.html
======
cmrx64
This is a lovely book. I gathered a group of students to work through this
book last year (and even roped in a professor). If you're interested in formal
software verification or interactive proof assistants, this is an excellent
and approachable introduction.

Another free book, using the Isabelle proof assistant, is [http://concrete-
semantics.org/](http://concrete-semantics.org/). It's also very good.

~~~
nextos
It looks very nice. The Little Prover, recently published is also a neat small
intro.

I wonder how does Software Foundations compare against other more specialized
classics in the field like [1-3].

[1] [https://mitpress.mit.edu/books/principles-model-
checking](https://mitpress.mit.edu/books/principles-model-checking)

[2]
[http://www.springer.com/fr/book/9783540654100](http://www.springer.com/fr/book/9783540654100)

[3]
[https://www.cis.upenn.edu/~bcpierce/tapl/](https://www.cis.upenn.edu/~bcpierce/tapl/)

~~~
cmrx64
I've worked through TaPL too. I'm not even sure they are comparable :) It's
possible to formalize the contents of TaPL in these systems (and, indeed,
Pierce has taught it like that). But it's still a very different focus than
Software Foundations.

I've not read or worked through the other books (wow they are expensive), but
I'm in general not very keen on model checking as an approach. Tools like
Alloy or NuSMV can be useful when designing or investigating algorithms, but
they always do a bounded search and can't be applied directly to
implementations. I personally don't confer that much trustworthyness to
systems that appeal to model checking tools for their correctness.

I've seen The Little Prover, but am somewhat wary of it. On the other hand, I
enjoyed The Little Schemer very much. I might take a look at it next month.

~~~
pron
> and can't be applied directly to implementations

There are model checkers that work directly on implementations, like NASA's
JPF.

> I personally don't confer that much trustworthyness to systems that appeal
> to model checking tools for their correctness.

Given that the going rate for proofs is roughly 1-1.5 days per one line of
code, which grows superlinearly with the code size, I think we have no
choice...

In any event, pretty much all safety-critical software that human lives depend
on (even many, many lives) is verified with model-checking in the best case.
Use of proofs in verifying safety-critical systems is very rare, as even those
domains can rarely afford it.

Also, remember that no one really needs 100% proof, as no other, non-software
component in the system guarantees 100% reliability (not that model-checking
can give us probability bounds).

~~~
tel
100% certainty in proof doesn't mean that you're aiming to get a 100% proven
system. It means that you can stop worrying about the proven part forevermore.
So it reduces long term running overhead.

~~~
pron
If your proven component is so well-isolated from others and doesn't undergo
changes (and neither do its assumptions about input), it seems like the same
would apply to a model-checked component. Besides, the cost of proofs is well
over 1Kx if not 10Kx over model checking, so I don't see how this
consideration is important.

Proofs are useful -- because of their total coverage -- when verifying
components that will be used in many different projects, like compilers,
kernels and libraries, and even then only when they are sufficiently small to
be doable within, say, 5-10 years by a dedicated team. A one-time gigantic job
will pay for itself by being used (and hopefully paid for) by many customers
over many years.

~~~
tel
I've got no problem with model checkers, though I'm not sure I agree with your
effort ratings. Different tools for different jobs, eh?

I think I also have a different conception of proof than you're naming. You
don't need to prove your entire program. 10 small proofs strung together can
go an enormous distance with low weight.

~~~
pron
I don't know. The spec I'm working on now is ~1300 lines of TLA+, and that's
just the essential core of the thing -- nowhere near the whole program. By
comparison, the Raft TLA+ spec is under third of that, yet the Verdi proof[1]
is ~50K LOC, took a whole team of _experts_ months of work, and didn't prove
liveness.

I have a very small sub-algorithm that I might try proving in TLA+ just to see
how it goes.

[1]: I couldn't find the original TLA+ proof online, but the author of the
Raft protocol said that he struggled even with partial machine-checked proofs.

~~~
tel
I don't think this is really surprising. I don't know a ton about distributed
systems, but the last time I read up on formalizing them and proving
properties it seemed like an incredibly daunting task. There's an exponential
blowup problem in that you end up having to follow every state in the state
spaces of every actor against every other state over time. I saw some
interesting proofs which used topological invariants to keep a hold of that
whole complex more delicately... but to actually just dive in and try
exhausting it cannot be simple.

~~~
pron
Well, formalizing them isn't too hard, and model-checking them is quite easy
(once you have a good formal spec), but proving them is another matter
altogether...

People prove specific algorithms (distributed, concurrent or sequential) with
TLA+, but once the spec is of a real system, things get much, much harder to
prove.

------
bkase
Certified Programming with Dependent Types (available online as well
[http://adam.chlipala.net/cpdt/](http://adam.chlipala.net/cpdt/)) is also a
good resource for learning Coq (note: I just started working through the
material this weekend).

------
davidgrenier
Whatever your views on that stuff... it is fun to play in Coq.

On the other hand, playing with J-Bob, the toy "proof assistant" used in The
Little Prover is tedious at best. I'm torn between just giving up with the
last two chapters of the book undone.

------
Pils
Working through this right now as a directed reading with a professor and a
couple of other students. Would definitely recommend this as a follow up to an
intro PL course.

------
krat0sprakhar
Can someone familiar with this kind of stuff lay out a few benefits of
learning this material for a practicing programmer? I'm quite interested
(since I've heard a lot about Coq and Pierce) but since there are so many
things to learn, I want to prioritize appropriately.

~~~
tel
It's hard to say exactly. It will teach you to think of programming in an
entirely new way.

Will that make it easier to write good code elsewhere? Almost certainly if
you're not familiar with mathematical proof (maybe you took a discrete math
course before). If you know what it is to prove then you'll learn an
interesting deep connection between programming and proving.

You probably don't want to prove things in your programs. Not really. Even
after you learn Coq it's too difficult to do day-to-day.

But proofs do not work without being completely consistent in the same way
that good programs are. So you can learn a lot of techniques for good programs
from techniques for good proofs. Coq rejects bad proofs, so it can be good
practice.

Finally, Coq is unashamedly higher-order. The chops you gain working with it
will translate more or less directly to better functional programming
comprehension.

------
javajosh
Uh, how do you pronounce Coq?

~~~
tel
As is traditional:

You pronounce it with an understanding of how difficult it must be to speak
French and have most of the CS world talk about bit twiddling.

~~~
pron
:)

------
auggierose
Looks like the book should have been called 'Playing with Coq' instead.

~~~
coolsunglasses
Is there some better resource for learning programs-are-proofs people should
be using?

~~~
auggierose
In my opinion, many people are curry Howard blind. It's like they found this
one correspondence between certain proofs (constructive ones) and programs and
are hell-bend on using it. Personally I like not to confuse the two things.
Proofs are proofs, programs are programs, programs can generate proofs, proofs
can verify programs. And proofs are classical.

~~~
mafribe
Identifying proofs with programs undeniably gives a beautiful economy of
concepts, best experienced among mature tools maybe in Agda.

But there is a price to be paid, and that's the restriction to constructive
logic. If you need classical logic, use an LCF-style prover like Isabelle/HOL.

~~~
pron
> But there is a price to be paid, and that's the restriction to constructive
> logic.

That's the price on the proof side. The price on the program side is the need
to encode complexity in the types because C-H is about abstract programs, not
computations.

Otherwise, the existence of a computation is entirely ignored except where it
may break the logic's consistency in the case of non-termination, but from the
computation's perspective, a long computation and a non-terminating one are
the same. The result is that you can "prove" the correctness of programs that
are effectively non-computable, i.e. programs that don't encode effective
computations (by effective computation I mean one that terminates before the
end of the universe, but it could be exchanged with more practical
definitions).

