Live data from Hacker News

If You're Not Writing a Program, Don't Use a Programming Language [video]

youtube.com

281–288 of 288 posts

Re: If You're Not Writing a Program, Don't Use a Programming Language [video]

#281
post #277

Earlier quoted context omitted.

> The set model is essentially the entire basis for CiC's claim to consistency. I am not saying that types do not have a set model, but that types and inhabitants are fundamentally separate. Or, put another way, a lambda term specifies a single (parameterized) execution (up to evaluation strategy), and that is the only thing that can be made to "run" (I'm sure there are ways to extract, say, a sole inhabitant of a ty…

> I'm talking about exponential differences in time complexity, or even infinite ones. You can easily specify "computations" with infinite (or even uncountable) nondeterminism in TLA. SQL joins are worst-case exponential in the number of relations joined, where n = the total number of rows in the database (though there are many special cases that can help reduce this). I believe many people nonetheless consider SQL a…

> I believe many people nonetheless consider SQL a programming language

Yes, but I don't think anyone considers a SQL join to be a description of a linear-time algorithm.

> Coq executes what you term the specification parts in a very different way than trying to exhaustively enumerate solutions--one that is actually quite efficient and can be mechanically executed.

I never said you always need to exhaustively enumerate solutions. Nevertheless, the problem of extracting a computation from a specification (e.g., an inhabitant from a type) is undecidable in general[1]. Hence, specifications cannot be generally compiled, therefore they are not programming languages.

They could be a new kind of programming language, where some search algorithm could sometimes find a computation, but that would be a "programming language" in a completely different sense; Lamport does acknowledge that possibility (I know some people are researching program generation, but the results so don't look very promising, and in any event no one expects them to ever be more than heuristic, even if they're ever effective).

[1]: I'm not sure what happens if you know the type is inhabited. I guess it will be decidable in that case (just as finding a proof of a proposition that's known to be a theorem), but the search is still intractable, and there is no way the resulting computation would be efficient.

Re: If You're Not Writing a Program, Don't Use a Programming Language [video]

#282
post #281

Earlier quoted context omitted.

> I'm talking about exponential differences in time complexity, or even infinite ones. You can easily specify "computations" with infinite (or even uncountable) nondeterminism in TLA. SQL joins are worst-case exponential in the number of relations joined, where n = the total number of rows in the database (though there are many special cases that can help reduce this). I believe many people nonetheless consider SQL a…

> I believe many people nonetheless consider SQL a programming language Yes, but I don't think anyone considers a SQL join to be a description of a linear-time algorithm. > Coq executes what you term the specification parts in a very different way than trying to exhaustively enumerate solutions--one that is actually quite efficient and can be mechanically executed. I never said you always need to exhaustively enumera…

> Yes, but I don't think anyone considers a SQL join to be a description of a linear-time algorithm.

This is the first mention either of us have had of "linear-time" outside of a discussion about specifications. There aren't many programming languages that only let you write linear-time algorithms, and I think that's very far from most people's definition of a programming language. That being said, it's not like you can't write linear-time algorithms in Coq; its reduction machine is pretty efficient w.r.t algorithmic complexity (and it's likely to gain native machine integers and arrays soon to bring the constant factor in line with this). Proving linear-time execution for a native Coq function is another question entirely, of course, but you can always model a specific reduction machine in Coq and analyze that instead.

> Hence, specifications cannot be generally compiled, therefore they are not programming languages

I really don't agree with you on this. You have a fixed notion in your head if what it means to compile a type (attempt to find an inhabitant), but that is not how Coq interprets types at all; from its perspective, types are terms of independent interest, and are moreover themselves inhabitants of some other type. We don't expect a program to try to "find the inhabitant" of a term of type boolean when it's compiled; we want to keep reducing the term until it's in normal form (and, hopefully, our theory is consistent so it will be either true or false). In Coq, the same sort of reasoning (more or less) applies to types; it just keeps reducing it until it reaches normal form. There's no special notion of "finding an inhabitant" as distinct from normal program execution, which is exactly why I claim that Coq does not make the "specification-program" distinction. I'm not sure if I can explain it any more simply. I am not saying this is not a meaningful distinction in TLA+, or that it's not a real concept, but it's not the only way of thinking about things.

> I'm not sure what happens if you know the type is inhabited. It might be decidable in that case (just as finding a proof of a proposition that's known to be a theorem), but the search is still intractable, and there is no way the resulting computation would be efficient.

Depends on the problem. In Coq, for decidable problems you can write a decision procedure that is tailored to the individual type, having it produce a proof of the proposition you desire as a byproduct (in fact, in general producing such a procedure is how you prove that the problem is decidable!). Sometimes executing it is tractable and sometimes it isn't, but I don't agree that writing an algorithm to solve such a problem automatically transforms your domain from "efficient, everyday programming" to "ineffecient, specification-driven programming." Moreover, a lot of the time, there will be an easy inefficient decision procedure and a much harder efficient one, but given that they're both written in the same language and solve the same problem it seems hard for me to imagine that one would be considered "ordinary programming" and the other "program extraction" or whatever.

(In response to your [1], tactic languages like Coq's Ltac, much maligned as they are, are basically an attempt at interactive program synthesis; people rarely write complicated proof terms by hand. So I'd say these ideas have been a success, though hardly an unqualified one. Of course, one can argue that it's not "really" synthesis because you're not synthesizing the whole program from nothing but the specification, but even in ordinary program synthesis most successful solutions are based on sketching, where a partial program is provided and the synthesis engine fills in the gaps).

Re: If You're Not Writing a Program, Don't Use a Programming Language [video]

#283
post #281

Earlier quoted context omitted.

> I believe many people nonetheless consider SQL a programming language Yes, but I don't think anyone considers a SQL join to be a description of a linear-time algorithm. > Coq executes what you term the specification parts in a very different way than trying to exhaustively enumerate solutions--one that is actually quite efficient and can be mechanically executed. I never said you always need to exhaustively enumera…

> Yes, but I don't think anyone considers a SQL join to be a description of a linear-time algorithm. This is the first mention either of us have had of "linear-time" outside of a discussion about specifications. There aren't many programming languages that only let you write linear-time algorithms, and I think that's very far from most people's definition of a programming language. That being said, it's not like you…

> This is the first mention either of us have had of "linear-time" outside of a discussion about specifications.

I mentioned it before, and my point isn't about linear time in particular. If you write a specification of an algorithm of time complexity T(n), the expectation is that interpreting the algorithm would take p(T(n)), where p is some polynomial (i.e. no exponential slowdown or worse). This is what I mean by "efficient".

> but that is not how Coq interprets types at all; from its perspective, types are terms of independent interest, and are moreover themselves inhabitants of some other type.

That doesn't matter. I can specify a function by giving it a type -- say it's a function from the even naturals to their Goldbach pairs. Turning this into a program requires finding a lambda term that computes such a function.

> There's no special notion of "finding an inhabitant" as distinct from normal program execution

What I meant was that a type in Coq is not a computation (although it could be the result of a computation), and a computation is not a type (although it could produce a type -- Pi types).

> I am not saying this is not a meaningful distinction in TLA+

In TLA+ there is no such distinction because you cannot talk about a program that computes that function, but always the set of all programs that do (you can, of course, give more and more detail to restrict the set, i.e., create subtypes, but there is no "the computation"); that set is always either empty or infinite. In fact, if it's non-empty, it's always too big to even be a set (it's a proper class).

> Sometimes executing it is tractable and sometimes it isn't, but I don't agree that writing an algorithm to solve such a problem automatically transforms your domain from "efficient, everyday programming" to "ineffecient, specification-driven programming."

I am not talking about writing an algorithm to solve such a problem automatically, but about a programming language that always does so.

> So I'd say these ideas have been a success, though hardly an unqualified one.

They have been an abysmal failure when it comes to synthesizing anything that could be considered a replacement for programming. But we're talking about two radically different measures of success. I'm talking about a commercial process of turning lead into gold, and you're talking about turning a couple of lead atoms into gold atoms in a particle accelerator.

Re: If You're Not Writing a Program, Don't Use a Programming Language [video]

#284
post #283

Earlier quoted context omitted.

> Yes, but I don't think anyone considers a SQL join to be a description of a linear-time algorithm. This is the first mention either of us have had of "linear-time" outside of a discussion about specifications. There aren't many programming languages that only let you write linear-time algorithms, and I think that's very far from most people's definition of a programming language. That being said, it's not like you…

> This is the first mention either of us have had of "linear-time" outside of a discussion about specifications. I mentioned it before, and my point isn't about linear time in particular. If you write a specification of an algorithm of time complexity T(n), the expectation is that interpreting the algorithm would take p(T(n)), where p is some polynomial (i.e. no exponential slowdown or worse). This is what I mean by…

> No, I mentioned it before, and my point isn't about linear time in particular. If you write a specification of an algorithm of time complexity T(n), the expectation is that interpreting the algorithm would take O(T(n)). This is what I mean by "efficient".

What algorithm? There are many algorithms that inhabit the same type. A specification that's detailed enough to be able to analyze its complexity is usually a program... and it's easy to write a program that runs in linear time in Coq.

> That doesn't matter. I can specify a function by giving it a type -- say it's a function from the naturals to their Goldbach pairs. Turning this into a program requires finding a lambda term that computes such a function.

In Coq, you cannot specify a function by giving its type. First, CiC is not an extensional type theory in general; it cares about how things are computed, not just what the answer is. Secondly, for many interesting function types in Coq, there are an infinite, or even uncountable, number of inhabitants (for example : Prop -> bool). Moreover, in Coq's core type theory, even if it could automatically find all lambda input-outputs pairs that inhabited some type, that would not be justification to replace the quantified type (you need to assume the function extensionality axiom if you want this).

> I didn't say there was. What I said was that a type in Coq is not a computation, and a computation is not a type. Just as a proof is not a proposition and a proposition is not a proof.

A type in Coq is no more or less a computation than a term is. I don't understand what this has to do with "specification vs programming." As for "a proposition is not a proof", I think that is the main point of significant disagreement between us. Why do you think True doesn't prove Prop, for instance? It may not be the most interesting proof in the world, but neither is the proof I of True (and in many cases, proofs of Prop are very interesting in themselves, particularly in the context of dependent elimination).

> In TLA+ there is no such distinction. You cannot talk about a program that computes that function, but always the set of all programs that do (i.e., just the type).

Okay, then neither of them have such a distinction. What you seem to be missing is that in Coq, the mechanism for manipulating types is not different from the mechanism for ordinary program evaluation; it looks like TLA+ uses an axiomatic formulation rather than computation rules, so if you were to add evaluation to TLA+ you'd probably need a new set of semantics, but that's not the case for Coq.

> I am not talking about writing an algorithm to solve such a problem automatically, but about a programming language that always does so.

As you noted, such a programming language is impossible, so I don't understand why you are talking about it. The impossibility of that hypothetical programming language doesn't mean you can't write a single unified programming language (without two different "parts") that also functions as a specification language, and I genuinely don't understand why you think it does.

> They have been an abysmal failure when it comes to synthesizing anything that could be considered a replacement for programming.

The state of this has been steadily improving! For example, https://www.cs.utexas.edu/~isil/sypet-popl17.pdf looks quite promising for everyday programming tasks.

Re: If You're Not Writing a Program, Don't Use a Programming Language [video]

#285
post #283

Earlier quoted context omitted.

> This is the first mention either of us have had of "linear-time" outside of a discussion about specifications. I mentioned it before, and my point isn't about linear time in particular. If you write a specification of an algorithm of time complexity T(n), the expectation is that interpreting the algorithm would take p(T(n)), where p is some polynomial (i.e. no exponential slowdown or worse). This is what I mean by…

> No, I mentioned it before, and my point isn't about linear time in particular. If you write a specification of an algorithm of time complexity T(n), the expectation is that interpreting the algorithm would take O(T(n)). This is what I mean by "efficient". What algorithm? There are many algorithms that inhabit the same type. A specification that's detailed enough to be able to analyze its complexity is usually a pro…

> A specification that's detailed enough to be able to analyze its complexity is usually a program...

Not necessarily, and I would claim that it usually isn't, but to see that you have to pay close attention to how algorithms and systems are specified. I give the example of the QuickSort algorithm at the beginning of this post: https://pron.github.io/posts/tlaplus_part3

> In Coq, you cannot specify a function by giving its type.

Of course you can; that's the meaning of the type -- it's just not enough to get a computation. That's precisely the point I was getting at. A specification is a description of something at some arbitrary level of detail, but languages that allow compilation -- i.e. programming language -- normally require a minimum level of detail for that to be possible. In a language like Coq, this requirement is a strict syntactic distinction between types and lambda terms.

> First, CiC is not an extensional type theory in general; it cares about how things are computed, not just what the answer is.

Precisely. This is absolutely necessary for a programming language, and undesired in a specification language. (BTW, in TLA, what and how is arbitrary, because the temporal logic lifts everything that in Coq is operational into the denotation)

> A type in Coq is no more or less a computation than a term is.

A type is not a computation. To "run" something, or to speak of the operation of something, that something must be a lambda term.

> the mechanism for manipulating types is not different from the mechanism for ordinary program evaluation

I know that (I don't know Coq, but I know a bit of Lean, which is similar, I think), but that doesn't matter. You can compute with types, but there is a strict distinction between the common form of nonderterministic specification -- types -- and actual computation (not types).

> As you noted, such a programming language is impossible, so I don't understand why you are talking about it.

Because we're trying to work out the difference between a specification language and a programming language. A programming language is one that, when it describes a computation, can always be interpreted efficiently in the sense I meant. A specification language should allow specifying computations at arbitrary levels of detail. I claim that a specification language cannot be a programming language and vice versa -- except if we had this magical language I described. What you can do, and Coq does, is combine two languages in one, but even then the result requires a delineation between a computation and a specification (arbitrary nondet).

> For example, https://www.cs.utexas.edu/~isil/sypet-popl17.pdf looks quite promising for everyday programming tasks.

I honestly do like the research, but this is going from converting two atoms of lead into gold in a particle accelarator to five, or like saying that Olympic high jumpers are steadily improving in jumping all the way to the moon... This is another discussion, but I like the research and I like the practice, but I don't buy the claims that such improvements in research put changes to practice on the horizon. The gap is still huge, and I also think some of the research (especially in programming language theory) is done based on assumptions that completely fail in practice (I wrote about that here: https://pron.github.io/posts/people-dont-write-programs)

Re: If You're Not Writing a Program, Don't Use a Programming Language [video]

#286

Earlier quoted context omitted.

Could you elaborate on how you came to be programming in C/C++ for 7 or 8 years before encountering a spreadsheet? That seems an unusual path even back in the 90s.

Ya I picked up my first programming book when I was 12, then started with HyperCard and Visual Interactive Programming (VIP) on the Mac Plus with my friend (another guy named Zack): https://en.wikipedia.org/wiki/HyperCard http://mstay.com/images/screens/vpc1.gif So thought of code as a big flowchart where you fill in the boxes with business logic. Transitioned to C within a year or two and got incredibly deep into as…

If you compare the ease of "authoring" in the top hypermedia environment of its day (Hypercard) with doing the same today (the web) it's plain as day that things have regressed.

Here is a straight up comparison someone made if anyone is interested:

https://twitter.com/ecgade/status/1029795513514774529

Re: If You're Not Writing a Program, Don't Use a Programming Language [video]

#287

Earlier quoted context omitted.

Are you sure, such thing as "high-assurance AI/ML" doesn't exist? Are you an expert in AI, with many years of experience building products with AI technology?

I'm not an expert in AI, but as you can imagine I have to interact with a lot of people who are. What I do know is what it means to be able to do end-to-end verification and it seems fairly antithetical to the basis of machine learning which has an open-ended failure domain. If you could write an AI as a total program, it would cease to be probabilistic. It would become propositional, but would also seem to cease to…

I work on the formal verification of AI systems as well, but focusing on model-based reasoning systems rather than the model-free ML systems. What you've described is exactly what terrifies me most about ML in safety critical contexts: it can fail in a large number of ways, and predicting these ahead of time is generally intractable.

I like to think of it in terms of quantifiers: for most systems it's fine to say that there exists a set of representative tests that the system passes. For critical systems, you really want "for all" in there instead.

Fortunately the model-based systems are much easier to reason about, even if they suffer from difficulty modeling certain cases. For a model-free system I think the starting point would be to precisely state a correctness criterion that could be used as a decision procedure on the output of the model; the combined system would be "verified" to a certain degree. Unfortunately you can't guarantee that it would always be able to yield an answer (it might always give a bad one which was rejected) and, the more fundamental problem, one might reasonably expect that if you can express the correctness property to a sufficient level of detail that you can perform verification on it you might be able to write an easier-to-verify implementation that doesn't rely on ML.

This stuff is hard, yo.

Re: If You're Not Writing a Program, Don't Use a Programming Language [video]

#288
post #10

I believe these are the kinds of ideas that might actually create a genuine engineering culture in software development. Until we start applying this kind of rigor to our work, I don't believe the title of "Software Engineer" is justified. It doesn't have to be TLA+; it doesn't have to be any particular tool or technology or pattern or whatever. But the attitude that rigor and formal technique is worth the additional…

I disagree that engineering is the best approach to writing software. I think this is the fundamental difference between people who prefer static vs dynamic typing. People who prefer static typing are more likely to say that one solution is more "correct" than the other, whereas dynamic typing allows more flexibility. I see writing software to be similar to writing music. Music has rules and structure, but leaves roo…

That might work fine if you're throwing together a blogging system, but not in a critical-systems software-engineering context. When the stakes are high, it doesn't do to view your code as a creative outlet.

Critical-systems software engineering is not about your creativity, it's about building maximally correct software, to minimise the probability of a catastrophic outcome.

This idea that it's inherently virtuous to let software developers be creative, strikes me as quite wrong-headed. If a strict methodology produces better results (and it does), a strict methodology should be adopted.

Bridge engineers don't whine about their constrained creativity. They're too busy ensuring their creations don't get anyone killed.

With the curious exception of Erlang et al, few people serious about program correctness favour dynamically typed languages. There's a reason why Ada is statically typed, and strongly typed (it lacks the dangerous implicit type conversions permitted by C).

An excellent article on this kind of thing: https://www.fastcompany.com/28121/they-write-right-stuff

Post reply on HN