Sometimes all functions are continuous (2006)
math.andrej.com
math.andrej.com
> An interesting question comes to mind: which programming features, apart from the ones we mentioned above, allow us to program [computably continuous integer streams]? In terms of Haskell, the same question is which monads allow us to program [these streams]?
> Can we do it without any extra features and use just “pure” functional programming?
> If by pure functional programming we understand a functional programming language with natural numbers, booleans and recusive definitions, also known as PCF, the answer is no. The proof of this uses denotational semantics and domain theory, and I will not go into it now. You may entertain yourself by trying and failing to define [computably continuous integer streams] in pure Haskell or ML, i.e., no side effects, no exceptions, no mutable store, no parallelism, no monads.
> ... The lesson is for those “experts” who “know” that all reasonable models of computation are equivalent to Turing machines. This is true if one looks just at functions from N to N. However, at higher types, such as the type of our function m, questions of representation become important, and it does matter which model of computation is used.
It takes a hit on the trend that was in vogue in early 2010s to do AI and metaphysics on top of Kolmogorov Complexity, Solmonoff Induction, information physics... people took the Turing Equivalence as a carte blanche to say whatever willy-nilly thing you want about the (potentially) computable nature of reality without being informed by more naturalistic methods.
This is harshed even further given that these information-theoretic arguments often used non-computable notions.
The continuum hypothesis is tangentially related to this topic and makes for fun reading.
From that definition, it's quite obvious that everything you compute has to be continuous, because you are never sure of what other decimals may be coming up, so whatever you compute has to be close enough.
That sounds more like an argument that representing numbers that way is not particularly useful since you can't do much with them (you can't even provide an equality operator).
> you can't even provide an equality operator
If you are given two rods, there is no way to tell if the two rods are of the same length.
I also don't really think you're using the right definition of computable here. You make it sound as though we're estimating, or truncating uncomputable numbers to make them computable when you say:
> From that definition, it's quite obvious that everything you compute has to be continuous, because you are never sure of what other decimals may be coming up, so whatever you compute has to be close enough.
It's not about being close enough or estimating, they're categorically different things. You can't obtain an uncomputable number, even by estimating, to any meaningful precision with a finite amount of time. So what are you saying here?
Hmm, I'm still stuck at this assertion. Why can we not assume the number is finite?
If we assume an infinitely long number takes an infinite amount of time to read, can we not also assume it must take an infinite amount of time to write? If we only have finite time, can we not assume all numbers given to the function in that time are finite?
The article seems to say that, because you can't produce an upper bound to the amount of time the sgn function will take to run (for all possible inputs), sgn isn't a function. But then... isn't it the same for every single other function?
I think the article is conflating "given a fixed amount of time, one can find an input for which the function will take longer to run" with "the function takes infinite time". The later isn't true: for any given input, no matter how big, one can compute a time such that the function will finish in that time; in other words, the function always finishes, in finite time, for every possible input, no matter how large.
It's possible we're both confused, I suppose. :-)
State is finite but time is countably infinite for our purposes, so we model infinite/unbounded things with programs that can run arbitrary long.
Finally, this abstract math stuff is in fact a really good UI point that most programmers miss. In non "real time" applications, you should aim to be able to dynamically tradeoff tardiness and richness; e.g. a fancy diagram that is rendered at low res and then higher res. Likewise all your caches should be evictable under memory pressure. Computing should feel fluid.
It's a pity most people only paleolithic state machine math or terminating thing math. This falsely implies that "real world programs" which hardly ever terminate are beyond theory, or that the smartypants thing to do is break them down into little terminating programs and some big spooky event loop whateverthefuck (browser, apache, framework du jour, etc etc.). Build codata out of codata!
Because it sounds like you’re simply redefining the terms. At which point you might as well be using “Spork”. Because, defining a new system has zero impact on a different system.
However, let's ignore that; the problem disappears if we define f(x ) = 1 at x = 1, and f(x) = 0 elsewhere.
In standard analysis that function would be discontinuous at that point.
I'm not sure about implications in the OP's kind of analysis. Would the existence of m(1) imply that there exist some smallest input that is larger than 1, that would make difference in output? Same for the largest input that is smaller than 1.
2. Behold https://en.wikipedia.org/wiki/Discrete_space . Topologies define continuinity, and here is a discrete topology.
3. With e.g. probability measures / expected values, which unify "discrete" and "continuous" statistics, you'll notice that there's lots of rules that are trivially obeyed in the discrete case, but take some care in the "continuous" case. For example, not ever set can have a measure in the latter but can in the former. This directly relates to discrete things being trivial to deem continuous. It's also a useful to define coarser topologies / event sigma-algebras in the finite case to better understand the issues are the unavoidable in the infinite cases. We only make the discrete discontinuous in that last "artificial" exercise.
I presume that you're allowing finite time execution of the equality-to-zero operation (I.e., a function that says if a number is equal to zero). If you don't, I suppose one would conclude (by applying the same arguments, whatever they are) that neither can a function that, say, adds numbers or does similarly trivial operations finish in finite time, in which case this distinction of finite- vs infinite-runtime functions isn't very interesting.
Any number that isn't zero and that starts with a zero (at the left of the dot), will always have a finite number of zero digits after the point. In other words, the only number that has a zero at the left of the dot (i.e., of the form 0.xyz...) that has an infinite number of zero decimals is zero itself.
I guess where we disagree is in this claim: "As you surely know, real numbers may have infinite amount of digits after the point". The only real numbers with this property are the integers. Every other real number has to have a finite number of zeros.
Every rational q is computable: λϵ.q
The sum of two computable reals, x and y, is computable: λx,y.λϵ.x(ϵ/2)+y(ϵ/2)
You can show the absolute value function is computable: λx.λϵ.|x(ϵ)|
So there are many trivial continuous functions like addition that are computable.
But the discontinuous function f(x)=1 if x=0, f(x)=0 otherwise, is not computable.
As a sampler, the following are all constructively false (ie. imply the law of excluded middle)
* Every finite set can be enumerated without repetitions
* A subset of a finite set is finite
* The intersection of finite sets is finite
For example, is A a subset of B={0}, if all you know about A is that it is a Java iteratable that returns 0 for the first 10^3000 elements you examine?
As a "practical" consequence: the common design of a random() function returning values in [0, 1) is wrong. Any function you write cannot "tell" whether it got a 1 or not.
These are still very good guidelines even for floating-point code, as long as you, like most everyone else, treat floats as a blackbox abstraction for "real" real numbers.
In fact, for float computations it's usually even more important to use continuous (ie. error tolerant) functions, since floating-point operations can introduce errors.
For another exposition of the same (or similar) results, see also Dan Piponi's post from 2008 "What does topology have to do with computability?" at http://blog.sigfpe.com/2008/01/what-does-topology-have-to-do...
Also, as a follow-up, you may be interested in Martin Escardo's 2007 post on the same blog: http://math.andrej.com/2007/09/28/seemingly-impossible-funct...
As a consequence, there are only two boolean-valued total functions: always return true, or always return false.
I guess that's why we don't use infinite streams of numbers for computation.
It's similar to the problem of comparing two natural numbers given in least significant bit order.
Maybe our domain should be limited to numbers generated by algorithms that are known to terminate? But despite eliminating irrational numbers, this guarantee doesn't seem like enough for practical computing. Even arbitrary precision algorithms require their inputs not only to be computable, but actually computed in advance, showing at least that they fit in memory.
[0]: https://home.sandiego.edu/~shulman/papers/rabbithole.pdf [1]: https://news.ycombinator.com/item?id=18411935
> Isn't it a little bit crazy to talk about computations on real numbers, when most of them are uncomputable/unnameable?
[1] https://arxiv.org/pdf/math/0411418.pdf
> Experimental physicists know how difficult accurate measurements are. No physical quantity has ever been measured with more than 15 or so digits of accuracy. Mathematicians, however, freely fantasize with infinite-precision real numbers. Nevertheless within pure math the notion of a real number is extremely problematic. We’ll compare and contrast two parallel historical episodes:
> 1. the diagonal and probabilistic proofs that reals are uncountable, and
> 2. the diagonal and probabilistic proofs that there are uncomputable reals.
> Both case histories open chasms beneath the feet of mathematicians.
For anything actually computable (in finite time), on computable (in finite time) values, you will always get discrete (not continuous) functions on discrete (not continuous) values.
This is actually a quite constructive notion! At least, it works well with intuinistic mathematics, which is why Andrej Bauer is writing about it.
Thank you!
Specifically, due to the fractal nature of a coastline the length diverges to infinity. The theoretical length at the infinite scale is infinity.
> the real number is not given by an infinite sequence that is actually written down anywhere, but rather as an algorithm, or a black box, which accepts a number n and outputs the n-th digit. At no point do I manipulate an infinite amount of information, yet I can look at any digit I want. Of course, I cannot look at all digits in a finite time, which is sort of the point of the post.