
Surprisingly Turing-Complete - kushti
http://www.gwern.net/Turing-complete
======
pjungwir
I have taken to calling certain features "Turing Complete" (in a joking-but-
not-really way). Most often they are seeking some kind of enterprise
customizability: "workflow", survey skip logic, custom reports, white
labeling, etc.---basically the same places where you risk falling into the
Inner Platform Effect trap. I'm curious how other people tackle requests for
these. Usually it starts out with something basic ("email the admin if it's
two weeks late", "skip this page if they answer that way", "use the most-
recently entered birthday to compute age in years and months", "let people
change the logo"), but I can see where it's going.

It seems to me you can either field these requests as they come in and get a
hodge-podge of strangely-interacting features, or you can build some kind of
general-purpose scriptability from the start. (Or you can follow the iPhone
and 37 Signals and do it one way only, but often that is not an option.) So
I've started to wonder about simply embedding a Javascript interpreter with
access to a well-defined API into your application objects. Then people can do
whatever they want! Of course this assumes savvy users, perhaps 90% an
internal "services" team. But JS is easy to embed, e.g. therubyracer, was
designed to be secure (no network/file/shell access), and is the most widely-
known of all programming languages. What do other people think? Crazy?

~~~
lmm
I don't favour anything that puts more Javascript out there, but I agree with
the more general point: if you're going to embed a programming language,
better to embed a real, well-designed one than an ad-hoc custom one.

This is also why I find the likes of drools and cucumber utterly wrongheaded.
(More generally, there's an antipattern of turing-complete configuration files
- often when an organization has convinced itself that "code" needs to go
through a long testing and deployment cycle but "configuration" doesn't). If
you already have a programming language, use it.

~~~
twic
Drools yes, but Cucumber? Cucumber isn't a programming language, it's just a
sequence of steps. There's no logic, iteration, calling, etc. There's
substitution of table values into steps, but that's no more programming than a
mail merge.

~~~
lmm
Tests end up needing logic, and so Cucumber ends up splitting the flow of a
test between two files in different languages.

I should probably have complained about HTML templating that allows a template
to call into functions (or have logic in it itself), that's a bigger and
clearer example of the problem.

I think the underlying principle here is that the more powerful languages need
to be outermost. Having a powerful language call into a weak language to do
something that needs to happen safely works well. Having a weak language call
into a powerful language just results in a worst of both worlds - all of the
danger but less of the power.

------
Grue3
I'm so tired of "CSS is Turing Complete" meme being propagated. TC is a
powerful result with important consequences. Namely the impossibility to solve
Halting problem. But CSS is deterministic and a CSS "program" always halts.

"But, but, we are making an _assumption_ that a user has to click this
particular button until the page doesn't change anymore (assuming infinitely
long page [1])"

To which I say, poppycock. The purpose of CSS language is to apply styles to
the webpage. Once it is processed, the CSS "program" has done it's purpose and
is finished (i.e. halted). Running the same CSS "program" over and over again
until it consistently produces identical results is not the point of CSS
(unlike, say LaTeX/BibTeX compilation process, where you need to compile one
file several times to get citation page numbers right, which _is_ Turing
complete). You might want to call it something else, like RCSS (repeated CSS).
Then, RCSS is Turing complete, but plain CSS isn't. Much like a calculator
that can calculate z^2 + C isn't necessarily Turing complete, while a
graphical calculator that can draw a Mandelbrot fractal by iterating that
formula is.

[1] which is acceptable, due to infinite memory assumption of a regular Turing
machine

~~~
gwern
I don't consider that a remotely relevant argument. CSS is intended to style
webpages at all times, webpages which are dynamic; CSS has never had a
'purpose' of rendering once and only once since oh, I don't know, 1997 or so.
You might as well object to the _Magic: the Gathering_ example because it
assumes a human to play each card mechanically; or you might as well object to
the very first Turing machine in Turing's paper because he asks us to assume a
setup where it's a human (or 'computer' as they were then known as) following
the instructions mechanically.

~~~
JesperRavn
While I question the tone of the original post, it is correct.

The difference between being Turing complete and implementing rule 110 is
crucial, and any discussion on the subject needs to make clear that these are
not the same.

You are obfuscating the role of the driver. In the Turing machine, the driver
is _part of_ the Turing machine. In CSS, it is not, and has to be done by the
user (or presumably a JS script).

As another post by Grue3 points out, almost any language can implement rule
110, including languages that are not Turing complete, and are explicitly said
not to be Turing complete in the CS literature/community.

For example, Coq, Agda, Idris (with totality checking) and other languages
based on Martin Lof type theory, are not Turing complete. That it why they are
able to prove totality of their functions. But they can all implement rule 110
with no problem.

~~~
JesperRavn
Just some more on dependently typed languages: The article actually mentions
them in footnote 1. So as it stands, the CSS part really doesn't make sense,
because everything written about CSS applies to these dependently typed
languages.

In particular, you could write some Agda/Coq/Idris program that implements
rule 110, and has some trivial user interaction to repeat this until a stable
pattern is reached. This simulates a Turing machine.

------
btilly
My favorite example is SQL. The ANSI-92 standard deliberately made SQL _not_
Turing Complete so that it could be optimized. But people kept adding things
to it, like CTE and windowing, and now it is.

See
[http://assets.en.oreilly.com/1/event/27/High%20Performance%2...](http://assets.en.oreilly.com/1/event/27/High%20Performance%20SQL%20with%20PostgreSQL%20Presentation.pdf)
for proof.

~~~
foobar2020
SQL took off as a way to wrap-up first-order logic over finite models into a
form useful for programmers:
[https://en.wikipedia.org/wiki/Relational_model](https://en.wikipedia.org/wiki/Relational_model)

------
exDM69
Here's a challenge for you guys: Super Mario Maker. It hasn't been proven
Turing complete yet, but I'd be surprised if it wasn't.

Here's a pointer for you to get started:
[http://www.gamefaqs.com/boards/805618-super-mario-
maker/7251...](http://www.gamefaqs.com/boards/805618-super-mario-
maker/72515728)

This guy says he has built a single nand gate, but hasn't been able to connect
several together.

As a gamer and a computer scientist, I find Turing complete games intriguing.
Minecraft's Redstone is probably intentionally Turing complete, but for
example the signalling of trains in OpenTTD probably is not.

~~~
panic
One big limitation in Super Mario Maker is that objects too far horizontally
offscreen are not simulated and may "de-spawn". Here's a more detailed
description of the rules:
[https://www.reddit.com/r/MarioMaker/comments/3lcrqb/super_ma...](https://www.reddit.com/r/MarioMaker/comments/3lcrqb/super_mario_maker_science_spawning_despawning_and/)

This means you have to include Mario's position in your design if the device
is larger than the horizontal simulation area. Just chaining together NAND
gates isn't necessarily enough.

~~~
steveklabnik
This was (is?) a problem in Minecraft as well, when people were first trying
to build CPUs in it.

------
crdoconnor
>Why this effort to make a language in which many programs can’t be written?
Because TC is intimately tied to Godel’s incompleteness theorems & Rice’s
theorem, allowing TC means that one is forfeiting all sorts of provability
properties: in a non-TC language, one may be able to easily prove all sorts of
useful things to know; for example, that programs terminate

Non-turing complete languages are also easier to reason about, less
susceptible to bugs and less susceptible to technical debt.

For this reason minimizing as much as possible the amount of turing complete
code you write will make your code cleaner.

Configuration and tests in particular are usually best described in a non-
turing complete language.

~~~
marcosdumay
>Non-turing complete languages are also ... less susceptible to technical
debt.

Well, except the technical debt of writing all the code in a language that may
not support solving your problem once you know it better.

~~~
crdoconnor
If it doesn't actually solve the problem you have a non-functional program,
not technical debt.

~~~
Moshe_Silnorin
You have a non-functional total functional program.

------
BrainInAJar
So many things are Turing complete for me anyway there's nothing surprising
about finding Turing completeness. What I find fascinating is useful languages
designed explicitly not to be Turing complete. It's a much harder task

~~~
danghica
Indeed. Agda and Coq are excellent examples.

------
davidgerard
Wikipedia's template language was not intended to be Turing-complete.

Then, through some hideous contortions of the syntax, someone managed to
construct an "if" statement.

This caused so much CPU load they implemented it as a function.

And then it evolved into a horrifying accidental DSL, ParserFunctions.

They're now trying to rewrite all those clever templates in Lua, having given
up avoiding Turing-completeness ...

The curse of Turing-completeness is: if you have it, you will soon _have to_
use it.

------
nutate
Interesting sub turing complete language:

[https://github.com/ainfosec/crema](https://github.com/ainfosec/crema)

------
moyix
Another list of "accidentally Turing complete" languages is here:

[http://beza1e1.tuxen.de/articles/accidentally_turing_complet...](http://beza1e1.tuxen.de/articles/accidentally_turing_complete.html)

Edit: Oops, I see this is already linked in the main article as “accidentally
Turing-complete”.

------
bbrazil
My personal contribution is
[http://demo.robustperception.io:9090/consoles/life.html](http://demo.robustperception.io:9090/consoles/life.html)

Who doesn't want a Turing Complete monitoring language?

------
kzrdude
Rust's type system was not meant to be turing complete, yet here we are.

Ref:
[https://www.reddit.com/r/rust/comments/2o6yp8/brainfck_in_ru...](https://www.reddit.com/r/rust/comments/2o6yp8/brainfck_in_rusts_type_system_aka_type_system_is/cmkrjz2)

~~~
kibwen
Alas, the compiler imposes an arbitrary recursion limit that makes the Turing-
completeness essentially useless. :)

------
mholt
Call me naive, but regarding:

> why a perfect antivirus program is impossible

What does TC have to do with a perfect antivirus program? Does it have
something to do with the Halting problem?

~~~
gwern
TC implies there's no such thing as a perfect antivirus program (which detects
all and only viruses), or a perfect typechecker etc because if you had such a
program, you could turn it into a halting-checker easily: for an AV program,
if you want to know if program X halts, you simply put the virus at the end
and run the whole thing through your perfect antivirus checker - by
assumption, if it detects a virus, then the program X must halt (otherwise the
virus would never be able to run and is just dead code) and if it doesn't
detect a virus, then program X doesn't halt. Since we know you can't solve the
halting problem... In more general terms, this brings us to Rice's theorem.

~~~
mjcohen
This was discussed in "Godel, Escher, Bach" in the form of trying to make a
record player that can play any record.

------
chromaton
TrueType fonts are apparently Turing Complete.

~~~
umanwizard
In this case it's intentional: they contain embedded bytecode programs for
hinting. (That is, adjusting what the font should look like under certain
conditions, e.g. low resolution)

------
amyjess
I dug into the CSS example before: it's not actually Turing-complete, but it
comes really close.

The user still has to manually intervene to advance each iteration of the
loop. It _would_ be Turing-complete except for that one little thing, but it's
not quite there.

~~~
simoncion
See gwern's rebuttal of this argument:
[https://news.ycombinator.com/item?id=10320076](https://news.ycombinator.com/item?id=10320076)

------
Drup
It's missing sql !

~~~
simoncion
I guess you missed the mention in the footnote.

------
tempodox
I've got a bunch of spaghetti that are Turing-complete (they form an analog
computing machine). I don't even want to think about the security
implications.

