News for hackers. Stuff that matters.
Re:Total Functional Programming [pdf] by vog on Wednesday October 05, 2016 @02:46PM (#12646606)
This is a very good explaination of that topic, creating languages which are not turing complete but still useful.

Also, I recommend reading Harper's throughts about it:

"Old Neglected Theorems Are Still Theorems" https://existentialtype.wordpress.com/2014/03/20/old-neglect...

It also reminds me of the NASA coding standards, rule 4:

"All loops must have a fixed upper-bound", see http://pixelscommander.com/en/javascript/nasa-coding-standar...

(Related HN discussion: https://news.ycombinator.com/item?id=8856226)

Re:Total Functional Programming [pdf] by wyager on Wednesday October 05, 2016 @02:52PM (#12646651)
The approach given in the paper explicitly allows for Turing completeness through the use of data/codata types. Instead of proving termination over codata you prove that a function "does something useful" every iteration.
Re:Total Functional Programming [pdf] by willtim on Wednesday October 05, 2016 @03:17PM (#12646873)
You would of course need to factor out the outer-loop to do this. But it seems even this is not necessary. This paper discusses using total languages to build generally recursive (Turing complete) computations as an effect monad: https://personal.cis.strath.ac.uk/conor.mcbride/TotallyFree....
Re:Total Functional Programming [pdf] by chriswarbo on Wednesday October 05, 2016 @05:25PM (#12648034)
One nice use of the "general recursion monad" idea is "mtac" ( http://plv.mpi-sws.org/mtac/ ), a "tactic language" for Coq. This allows meta-programming, to calculate what a value/function/etc. should be, which is really useful for proof objects (i.e. values which are required for compilation, but have no effect on runtime computation).

A tactic language doesn't need to be total, since it's only run at compile-time, so no errors can leak into the resulting proof/program. The worst that can happen is the compiler hangs.

Coq comes with "ltac", which is a horrible imperative language that leads to very fragile proofs. On the other hand, mtac is just Coq's normal, total FP language ("gallina"). A monad is used to wrap up general recursion, so that gallina can be used un-changed.

During compilation, these monadic values are forced, which either leads to a value or causes the compiler to hang. This is a really nice compromise, since you can write Haskell-style FP code which "obviously terminates", without having to prove that it terminates, you still have access to all of the nice dependent type machinery, and the end result (the program, not the meta-program) is guaranteed to be total (unlike, say, an Idris function which turns off the totality checker).

Re:Total Functional Programming [pdf] by wyager on Wednesday October 05, 2016 @04:05PM (#12647311)
> You would of course need to factor out the outer-loop to do this

What are you referring to? Data/codata checking works with local type inference.

Re:Total Functional Programming [pdf] by mkehrt on Wednesday October 05, 2016 @08:21PM (#12649143)
Essentially, to get a nonterminating, program, your top level function needs to take a piece of codata to corecurse over to run indefinitely. Since you can't actually write a program that takes no arguments that produces an infinite piece of data, all programs must terminate.
Re:Total Functional Programming [pdf] by wyager on Thursday October 06, 2016 @02:43PM (#12654945)
>Since you can't actually write a program that takes no arguments that produces an infinite piece of data

Huh?

    inf = Cons 1 inf
Re:Total Functional Programming [pdf] by mkehrt on Thursday October 06, 2016 @06:00PM (#12656491)
Hm, you may be right. I though that was going to violate:

> Each recursive function call must be on a syntactic subcomponent of its formal parameter.

But it doesn't. But you can't actually use that to get a nonterminating program, because you can't recurse over it:

> Ordinary recursion is not legal over codata, because it might not terminate.

Re:Total Functional Programming [pdf] by cousin_it on Thursday October 06, 2016 @07:23AM (#12651547)
For me, Turing completeness means being able to implement every computable function of type Integer -> Integer. Total languages can't do that. They need an additional input that bounds the number of steps, but the whole point of Turing completeness is not needing that input, but rather being able to run any Turing machine until it stops on its own. Otherwise you'd be forced to conclude that many languages known to be not Turing complete, like the simply typed lambda calculus, are Turing complete in disguise, and the definition loses all teeth.

This is similar to the Brown-Palsberg self-interpreter in a total language, which caused a lot of confusion recently because it's not a self-interpreter (it doesn't take source code as an argument). I think it's better to stick with common definitions and accept that total languages are not Turing complete and can't self-interpret.

Re:Total Functional Programming [pdf] by pron on Thursday October 06, 2016 @08:43AM (#12651910)
There's a subtlety here. Total functional languages are necessary when the language is used as a general theorem prover via propositions-as-types (it is a common error -- but an error nonetheless -- to believe that totality has a non-negligible effect on proving correctness of computations; for all intents and purposes, the halting theorem still holds, as its bounded version -- which is what matters -- does not require self-interpretation for diagonalization). Now, for this to work, any computation that is represented as a function -- how computations are normally represented in functional languages -- must provably terminate, otherwise an inconsistency may be introduced into the logic corresponding to the program (this inconsistency does not apply when actual computations are concerned, only when the program represents a general mathematical theorem). However, computations may be represented not as functions but as monads, too, and introducing a monad that, while not implementable in the language itself, loops forever does not harm the totality that matters to theorem proving.
Re:Total Functional Programming [pdf] by tome on Thursday October 06, 2016 @05:26PM (#12656250)
> it is a common error -- but an error nonetheless -- to believe that totality has a non-negligible effect on proving correctness of computations

Is it a common error? Who's commonly saying this? Can you link any examples? It seems a really strange claim to make.

Re:Total Functional Programming [pdf] by pron on Friday October 07, 2016 @01:36AM (#12658423)
> Can you link any examples

There are a couple in this very discussion:

https://news.ycombinator.com/item?id=12648261

https://news.ycombinator.com/item?id=12648932

A quick Google search I did just now came up with this one, by someone who knows better[1]: By writing programs in a total language like this, you can confidently answer questions that you can't with a Turing-complete language. You've overcome theoretical limitations by changing the problem parameters a little bit—a common approach in engineering.

The only question you can confidently answer is "does the program halt", to which the answer is always yes. You cannot confidently answer any other question any easier than in non-total languages.

You can find more examples in recent discussions about the Ethereum heist, with many suggestions to "just use a non-Turing complete language". Many seem to believe that there are languages that make verification easy, or that Turing completeness is the problem.

> It seems a really strange claim to make

I guess the reasoning goes like this: the impossibility of proving things in general about programs is a result of the halting theorem; we can get around the halting theorem by using languages that only admit programs that halt; assuming the language is still useful -- problem solved!

How many people know about bounded halting? I know I hadn't until rather recently, when I thought about it and somebody pointed out to me that it's at the very core of the time-hierarchy theorem. I think I actually thought about it because of total languages, when I realized that every program can be assumed to be total without loss of generality, and so totality cannot add actionable information.

[1]: https://www.quora.com/Can-we-solve-the-halting-problem-by-de...

Re:Total Functional Programming [pdf] by wyager on Thursday October 06, 2016 @03:01PM (#12655113)
You can't write every possible term of that type. However, you can write a program that performs the same computation as any expression of that type by explicitly breaking recursion out, e.g. via

     Free (() ->) Integer
And then using corecursion to evaluate this step by step.

The actual definition of Turing completeness is the ability to implement any program that a Turing machine can compute, which you can with corecursion.