<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mathematics and Computation &#187; Programming</title>
	<atom:link href="http://math.andrej.com/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://math.andrej.com</link>
	<description>Mathematics for computers</description>
	<lastBuildDate>Thu, 29 Jul 2010 13:18:21 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Random art in Python</title>
		<link>http://math.andrej.com/2010/04/21/random-art-in-python/</link>
		<comments>http://math.andrej.com/2010/04/21/random-art-in-python/#comments</comments>
		<pubDate>Wed, 21 Apr 2010 07:15:29 +0000</pubDate>
		<dc:creator>Andrej Bauer</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Random art]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://math.andrej.com/?p=505</guid>
		<description><![CDATA[<p>I get asked every so often to release the source code for my random art project. The original source is written in Ocaml and is not publicly available, but here is a simple example of how you can get random art going in python in 250 lines of code.</p>
<p>Download source: randomart.py</p>
<p></p>
<p>The idea is to generate [...]]]></description>
			<content:encoded><![CDATA[<p>I get asked every so often to release the source code for my <a href="http://www.random-art.org/">random art</a> project. The original source is written in Ocaml and is not publicly available, but here is a simple example of how you can get random art going in python in 250 lines of code.</p>
<p><strong>Download source:</strong> <a title="Random art" href="/wp-content/uploads/2010/04/randomart.py">randomart.py</a></p>
<p><span id="more-505"></span></p>
<p>The idea is to generate expression trees that describe an image. For each point `(x,y)` of the image we evaluate the expression and get a color. A color is represented as a triple `(r,g,b)` where the red, green, blue components are numbers between `-1` and `1`. In computer graphics it is more usual to use the range `[0,1]`, but since many operations are symmetric with respect to the origin it is more convenient to use the interval `[-1,1]`.  I kept the program as simple as possible, and independent of any non-standard Python libraries. Consequently, a number of improvements and further experiments are possible:</p>
<ul>
<li>The most pressing problem right now is that the image is displayed as a large number of rectangles of size 1&#215;1 on the tkinter Canvas, which consumes a great deal of memory. You will not be able to draw large images this way. An improved version would use the Python imagining library (PIL) instead.</li>
<li>The program uses a simple <a href="http://en.wikipedia.org/wiki/RGB_color_model">RGB (Red Green Blue) color model</a>. We could also use the <a href="http://en.wikipedia.org/wiki/HSL_and_HSV">HSV model (Hue Saturation Value)</a>, and others. One possibility is to generate a palette of colors and use only colors that are combinations of those from the palette.</li>
<li>Of course, you can experiment by introducing new operators. If you are going to play with the source, your first exercise should be a new operator. Make sure it maps the range `[-1,1]` back to `[-1,1]`.</li>
<li>The program uses cartesian coordinates. You could experiment with polar coordinates.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://math.andrej.com/2010/04/21/random-art-in-python/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Tutorial on exact real numbers in Coq</title>
		<link>http://math.andrej.com/2010/01/07/tutorial-on-videolecturesnet/</link>
		<comments>http://math.andrej.com/2010/01/07/tutorial-on-videolecturesnet/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 18:06:26 +0000</pubDate>
		<dc:creator>Andrej Bauer</dc:creator>
				<category><![CDATA[Computation]]></category>
		<category><![CDATA[Constructive math]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://math.andrej.com/?p=417</guid>
		<description><![CDATA[<p>Already a while ago videolectures.net published this tutorial on Computer Verified Exact Analysis by Bas Spitters and Russell O&#8217;Connor from Computability and Complexity in Analysis 2009. I forgot to advertise it, so I am doing this now. It is about an implementation of exact real arithmetic whose correctness has been verified in Coq. Russell also [...]]]></description>
			<content:encoded><![CDATA[<p>Already a while ago <a href="http://www.videolectures.net">videolectures.net</a> published this <strong><a href="http://videolectures.net/aug09_spitters_oconnor_cvia/">tutorial on Computer Verified Exact Analysis</a></strong> by <a href="http://www.cs.ru.nl/~spitters/">Bas Spitters</a> and <a href="http://r6.ca/">Russell O&#8217;Connor</a> from <a href="http://cca-net.de/cca2009/">Computability and Complexity in Analysis 2009</a>. I forgot to advertise it, so I am doing this now. It is about an implementation of exact real arithmetic whose correctness has been verified in Coq. Russell also gave a quick tutorial on Coq.</p>
]]></content:encoded>
			<wfw:commentRss>http://math.andrej.com/2010/01/07/tutorial-on-videolecturesnet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Constructive gem: double exponentials</title>
		<link>http://math.andrej.com/2009/10/12/constructive-gem-double-exponentials/</link>
		<comments>http://math.andrej.com/2009/10/12/constructive-gem-double-exponentials/#comments</comments>
		<pubDate>Sun, 11 Oct 2009 22:58:10 +0000</pubDate>
		<dc:creator>Andrej Bauer</dc:creator>
				<category><![CDATA[Gems and stones]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://math.andrej.com/?p=338</guid>
		<description><![CDATA[<p>In the last constructive gem we studied the exponential `2^NN` and its isomorphic copies. This time we shall compute the double exponential `2^(2^NN)` and even write some Haskell code.</p>
<p>By `2` we mean the set `{0,1}` of the Boolean values. First note that there is a difference between `(2^2)^NN` and `2^(2^NN)`. The former is isomorphic to [...]]]></description>
			<content:encoded><![CDATA[<p>In the last constructive gem we studied the exponential `2^NN` and its isomorphic copies. This time we shall compute the <em>double</em> exponential `2^(2^NN)` and even write some Haskell code.<span id="more-338"></span></p>
<p>By `2` we mean the set `{0,1}` of the Boolean values. First note that there is a difference between `(2^2)^NN` and `2^(2^NN)`. The former is isomorphic to the Cantor space `2^NN` because `(2^2)^NN = 2^(2 \times NN) = 2^NN`, while the latter is the space of <em>functionals</em>, which are maps from infinite binary sequences to bits. In Haskell we would define these as</p>
<blockquote>
<pre>type Nat = Int -- notational convenience
type Natural = Integer -- notational convenience
type Cantor = Nat -&gt; Bool
type Functional = Cantor -&gt; Bool</pre>
</blockquote>
<p>Throughout we will write `0` and `1` for false and true, but convert them to Boolean values <code>False</code> and <code>True</code> in Haskell code. You may download all Haskell code from this post in one chunk here: <a href="/wp-content/uploads/2009/10/double.hs">double.hs</a>.</p>
<p>What can we say about `2^(2^NN)`? In classical set theory the basic observation is that `2^NN` has the cardinality of continuum, and that `2^(2^NN)` has cardinality even greater than that, but it is undecidable from the standard axioms of set theory whether the cardinality of `2^(2^NN)` is `aleph_2` or something larger (this is an instance of the <a href="http://en.wikipedia.org/wiki/Continuum_hypothesis#The_generalized_continuum_hypothesis">Generalized Continuum Hypothesis</a>). There seems to be no consensus among set theorists about what the answer should be. Is there a consensus among constructive mathematicians?</p>
<p>Because constructive mathematics is &#8220;backwards compatible&#8221; with classical mathematics, we cannot be specific about `2^(2^NN)` without assuming additional axioms. And this is where fun begins with constructive mathematics: assume an axiom which contradicts classical logic and see what happens (set theorists do something similar with their non-standard axioms, except that theirs are compatible with classical logic). Of course, such axioms do not just drop from the sky, they are always well motivated by some aspect of computation or geometry. I should warn you that the anti-classical axioms are the mathematical equivalent of psychoactive drugs: they take some getting used to, they are addictive and warp your sense of reality.</p>
<p>Before we digest the axiom let us ask what sort of functionals we are able to come up with constructively. An easy one would be &#8220;evaluate at `n`&#8221;, defined as</p>
<blockquote><p>`E_n(alpha) = alpha(n).`</p></blockquote>
<p>(We use lower-case Greek letters for infinite binary sequences and capital letters for functionals.) Or we can combine several bits of a sequence with a Boolean function, such as</p>
<blockquote><p>`F(alpha) = alpha(0) and (alpha(7) or not alpha(13)).`</p></blockquote>
<p>This particular functional has the property that there is a constant, namely `13`, such that its value depends only on the bits `0` through `13` of `alpha` (of course it only depends on bits `0`, `7` and `13`, but we will just keep track of the highest bit on which the functional depends). In general, we say that a functional `F in 2^(2^NN)` is <em>uniformly continuous</em>, if it has a <em>modulus (of uniform continuity)</em>, which is a number <em> </em>`k in NN` such that `F(alpha) ` depends only on the bits `0` through `k` of `alpha`. The terminology comes from the fact that such functionals are precisely the uniformly continuous maps from the Cantor space `2^NN` to the discrete space `2`. (I leave it as exercise for you to define the suitable metric on `2^NN`, constructively of course.)</p>
<p>A uniformly continuous functional may be represented by a finite amount of information as follows. Every functional `F \in 2^(2^NN)` can be decomposed uniquely into two functionals `F_0` and `F_1` such that</p>
<blockquote><p>`F(alpha) = F_0(lambda n. alpha(n+1))` when `alpha(0) = 0`,<br />
`F(alpha) = F_1(lambda n. alpha(n+1))` when `alpha(0) = 1`.</p></blockquote>
<p>The decomposition corresponds to investigating the first bit of the input `alpha` and making a decision based on that. In terms of exponential arithmetic, the decomposition of `F` into `F_0` and `F_1` corresponds to the isomorphism</p>
<blockquote><p>`2^(2^NN) = 2^(2^(1 + NN)) =  2^(2 \times 2^NN) = (2^(2^NN))^2 = 2^(2^NN) \times 2^(2^NN).`</p></blockquote>
<p>We may decompose `F_0` and `F_1` further into `F_(00)`, `F_(01)`, `F_(10)`, and `F_(11)`, and keep going. If `F` is uniformly continuous with modulus `k` then after `k` decompositions we get constant functionals. Thus we can represent every uniformly continuous functional with an element of the inductive type</p>
<blockquote>
<pre>data UCF = Const Bool | Decompose UCF UCF</pre>
</blockquote>
<p>The functional which always returns the value <code>b</code> is represented by <code>Const b</code>, whereas <code>Decompose x y</code> represents the functional whose decompositions `F_0` and `F_1` are represented by <code>x</code> and <code>y</code>, respectively. The Haskell function that converts the representation into a functional is:</p>
<blockquote>
<pre>fn :: UCF -&gt; Functional
fn (Const b) alpha = b
fn (Decompose x y) alpha = fn (if alpha 0 then y else x) (\n -&gt; alpha (n+1))</pre>
</blockquote>
<p>Unfortunately, every functional has infinitely many representations because we may keep decomposing even if the functional is constant. For example, the functional `F(alpha) = 0` can be represented by <code>Const False</code>, or <code>Decompose (Const False) (Const False)</code>, and so on. This will not do for our purposes. We need a representation that represents each uniformly continuous functional uniquely. Furthermore, we want the representation expressed as an inductive type, so we cannot just take the above representation and remove some elements from it.</p>
<p>After a day of head scratching and a nudge in the right direction by <a href="http://www.fmf.uni-lj.si/~cabello/">Sergio Cabello</a>, I came up with the following representation. A uniformly continuous functional `F in 2^(2^NN)` is either constant or non-constant, and a non-constant functional `F` has precisely one of the following forms:</p>
<ul>
<li>`F(alpha) = (alpha(0) = b)` for a unique `b in {0,1}`, i.e., `F` makes its decision by looking at the head of `alpha`, or</li>
<li>`F(alpha) = (alpha(0) = b) and G(lambda n. alpha(n+1))` for a unique `b in {0,1}` and a unique non-constant `G`, or</li>
<li>`F(alpha) = (alpha(0) = b) or G(lambda n. alpha(n+1))` for a unique `b in {0,1}` and a unique non-constant `G`, or</li>
<li>`F(alpha)` decomposes uniquely into non-constant functionals `F_0` and `F_1`, as above.</li>
</ul>
<p>This leads to the following two-stage definition in Haskell:</p>
<blockquote>
<pre>-- representation of non-constant functionals
data UCF' = Head Bool
          | And Bool UCF'
          | Or Bool UCF'
          | Decompose UCF' UCF'
            deriving (Eq, Show)

-- representation of arbitrary functionals
data UCF = Const Bool
         | Nonconst UCF'
           deriving (Eq, Show)</pre>
</blockquote>
<p>Here are the maps that convert representations to functionals:</p>
<blockquote>
<pre>-- convert a non-constant representation to the functional
fn' :: UCF' -&gt; Functional
fn' f alpha = compute 0 f
    where compute k (Head b) = (alpha k == b)
          compute k (And b x) = (alpha k == b) &amp;&amp; (compute (k+1) x)
          compute k (Or b x) = (alpha k == b) || (compute (k+1) x)
          compute k (Decompose x y) = (alpha k == False &amp;&amp; compute (k+1) x) ||
                                      (alpha k == True &amp;&amp; compute (k+1) y)

-- convert a representation to the functional
fn :: UCF -&gt; Functional
fn (Const b) = const b
fn (Nonconst x) = fn' x</pre>
</blockquote>
<p>So much about uniformly continuous functionals. What about the non-uniformly continuous ones?  Here is one:</p>
<blockquote><p>`F(alpha) = 1` when `forall n in NN, alpha(n) = 0`,<br />
`F(alpha) = 0` otherwise.</p></blockquote>
<p>Unfortunately, this is not a constructively valid definition because it presupposes that every `alpha in 2^NN` is equal to the zero sequence or not. Here is another attempt:</p>
<blockquote><p>`F(alpha) = 0` if the least `n in NN` for which `alpha(n) = 1` is even,<br />
`F(alpha) = 1` if the least `n in NN` for which `alpha(n) = 1` is odd.</p></blockquote>
<p>This is a constructive definition (you can easily translate it into Haskell), the functional is not uniformly continuous, but unfortunately it is not <em>total</em> either because its value is undefined when `alpha` is the zero sequence. Try as hard as you may, you will not be able to define constructively a functional which is not uniformly continuous. If you can&#8217;t beat them, join them:</p>
<blockquote><p><strong>Axiom:</strong> <em>All functionals `2^NN -&gt; 2` are uniformly continuous.</em></p></blockquote>
<p>I am going to convince you that the axiom is true, or more precisely that it <em>could</em> be true, by writing in Haskell the inverse of <code>fn :: UCF -&gt; Functional</code>, thus witnessing the fact that in the Haskell world <em>every</em> functional has a <code>UCF</code> representation and so is uniformly continuous. But first let me just mention that books on constructive mathematics never phrase the axiom in the above form. In Brouwerian intuitionism our axiom is actually a theorem which follows from two more basic principles (I am misrepresenting them a bit, I hope the experts won&#8217;t mind):</p>
<blockquote><p><strong>Continuity principle:</strong> <a href="/2006/03/27/sometimes-all-functions-are-continuous/"><em>All maps are continuous.</em></a></p>
<p><strong>Fan Principle:</strong> <em>The Cantor space is compact.</em></p></blockquote>
<p>It&#8217;s not too hard to derive our axiom from these two (compactness here is meant in the sense of Heine-Borel: every cover of the Cantor space by open balls has a finite subcover). If you want to know more about this topic, see:</p>
<blockquote><p>D. Bridges, H. Ishihara, and P. Schuster: <em>‘Compactness and continuity, constructively revisited</em>’ in: <em>Computer Science Logic </em>(J. Bradfield, ed; Proceedings of 16th International Workshop CSL 2002, 11th Annual Conference of the EACSL, Edinburgh, Scotland, September 22–25), Lecture Notes in Computer Science 2471, 89–102, Springer–Verlag, Berlin and Heidelberg, 2002.</p></blockquote>
<p>There is an evil Springer <a href="http://www.springerlink.com/content/nck0v2atr5auxjve/">link</a> to the paper that wants to sell it to you for 25 USD, and unfortunately none of the authors published it on the web.</p>
<p>To define the inverse of <code>fn</code> I will use <a href="/2007/09/28/seemingly-impossible-functional-programs/">seemingly impossible functionals</a> by <a href="http://www.cs.bham.ac.uk/~mhe/">Martin Escardo</a>. Here&#8217;s a fairly fast version of his quantifiers:</p>
<blockquote>
<pre>-- Martin Escardo's find, forevery and forsome functionals
find :: Functional -&gt; Cantor
find p = branch x l r
    where branch x l r n |  n == 0    = x
                         |  odd n     = l ((n-1) `div` 2)
                         |  otherwise = r ((n-2) `div` 2)
          x = forsome (\l -&gt; forsome (\r -&gt; p (branch True l r)))
          l = find (\l -&gt; forsome (\r -&gt; p(branch x l r)))
          r = find (\r -&gt; p (branch x l r))

forevery, forsome :: Functional -&gt; Bool
forsome f = f (find f)
forevery f = not (forsome (not . f))</pre>
</blockquote>
<p>You don&#8217;t have to understand this (although you really should, read <a href="/2007/09/28/seemingly-impossible-functional-programs/">the post</a>), just remember that <code>forevery f</code> is <code>True</code> precisely when <code>f</code> always returns <code>True</code>. This allows us to detect whether a functional `f` is constant by checking whether `f(alpha) = f(lambda n. 0)` for all `alpha in 2^NN`. Here&#8217;s the function we need:</p>
<blockquote>
<pre>-- get_const f returns Just b if f is constantly b, and Nothing otherwise
get_const :: (Functional) -&gt; Maybe Bool
get_const f =
    let b = f (const False) in
    if forevery (\alpha -&gt; f alpha == b) then Just b else Nothing</pre>
</blockquote>
<p>And here is the inverse of <code>fn</code>, there is no point in explaining the code, just stare at it for a while:</p>
<blockquote>
<pre>-- in order to define the inverse of fn we need an auxiliary function shift
prepend :: Bool -&gt; (Nat -&gt; Bool) -&gt; (Nat -&gt; Bool)
prepend b alpha 0 = b
prepend b alpha (n+1) = alpha n

shift :: Bool -&gt; (Functional) -&gt; Functional
shift b f = f . (prepend b)

-- the inverse of fn' computes the representation of a non-constant functional
unfn' :: Functional -&gt; UCF'
unfn' f = case (get_const (shift False f), get_const (shift True f)) of
            (Just True, Just False) -&gt; Head False
            (Just False, Just True) -&gt; Head True
            (Just False, Nothing) -&gt; And True (unfn' (shift True f))
            (Nothing, Just False) -&gt; And False (unfn' (shift False f))
            (Just True, Nothing) -&gt; Or False (unfn' (shift True f))
            (Nothing, Just True) -&gt; Or True (unfn' (shift False f))
            (Nothing, Nothing) -&gt; Decompose (unfn' (shift False f)) (unfn' (shift True f))

-- finally, the inverse of fn computes the representation of a functional
unfn :: Functional -&gt; UCF
unfn f = case get_const f of
           Just b -&gt; Const b
           Nothing -&gt; Nonconst (unfn' f)</pre>
</blockquote>
<p>Let&#8217;s try it out:</p>
<blockquote>
<pre>&gt; <strong>let f alpha = alpha 0 || alpha 2</strong>
&gt; <strong>unfn f</strong>
Nonconst (Or True (Decompose (Head True) (Head True)))
&gt; <strong>let g = fn (unfn f)</strong>
&gt; <strong>forevery (\alpha -&gt; f alpha == g alpha)</strong>
True</pre>
</blockquote>
<p>In a sense we computed the double exponential `2^(2^NN)` to be isomorphic to the inductive datatype <code>UCF</code>. But this is ugly and we can do better, namely</p>
<blockquote><p>`2^(2^NN) = NN.`</p></blockquote>
<p>If you think this is weird, remember that you just took in an anti-classical axiom. To establish the equality we have to show that `NN` is isomorphic to <code>UCF</code>. This is not complicated as <code>UCF</code> is an inductive type: the low bits of a number are used as tags for alternatives and the high bits for the data:</p>
<blockquote>
<pre>-- encode a pair of numbers by interleaving their bits
pair :: Natural -&gt; Natural -&gt; Natural
pair 0 0 = 0
pair m n = let (mq, mr) = divMod m 2
               (nq, nr) = divMod n 2
           in mr + 2 * nr + 4 * pair mq nq

-- decode a pair of numbers
unpair :: Natural -&gt; (Natural, Natural)
unpair 0 = (0, 0)
unpair n = let (p,xr) = divMod n 2
               (q,yr) = divMod p 2
               (x,y) = unpair q
           in (xr + 2*x, yr + 2*y)

-- enumeration of all elments of UCF' without repetitions
enum' :: Natural -&gt; UCF'
enum' 0 = Head False
enum' 1 = Head True
enum' (n+2) = case n `mod` 5 of
                 0 -&gt; And False (enum' (n `div` 5))
                 1 -&gt; And True (enum' (n `div` 5))
                 2 -&gt; Or False (enum' (n `div` 5))
                 3 -&gt; Or True (enum' (n `div` 5))
                 4 -&gt; Decompose (enum' n0) (enum' n1) where (n0, n1) = unpair (n `div` 5)

-- the inverse of enum' computes the index of a given representation
denum' :: UCF' -&gt; Natural
denum' (Head False) = 0
denum' (Head True) = 1
denum' (And False x) = 2 + 5 * denum' x
denum' (And True x) = 3 + 5 * denum' x
denum' (Or False x) = 4 + 5 * denum' x
denum' (Or True x) = 5 + 5 * denum' x
denum' (Decompose x y) = 6 + 5 * pair (denum' x) (denum' y)

-- enumeration of all elements of UCF without repetitions
enum :: Natural -&gt; UCF
enum 0 = Const False
enum 1 = Const True
enum (n+2) = Nonconst (enum' n)

-- the inverse of enum computes the index of a given representation
denum :: UCF -&gt; Natural
denum (Const False) = 0
denum (Const True) = 1
denum (Nonconst x) = 2 + denum' x</pre>
</blockquote>
<p>The isomorphisms between `2^(2^NN)` and `NN` are <code>denum.unfn</code> and <code>fn.enum</code>. They work faster than I expected. For example, computing the code of the functional `F(alpha) = alpha(0) and (alpha(7) or not alpha(13))` from above takes two seconds on my old Thinkpad X41 tablet with GHCi 6.8.2:</p>
<blockquote>
<pre>&gt; <strong>denum (unfn (\alpha -&gt; alpha 0 &amp;&amp; (alpha 7 || not (alpha 13))))</strong>
87817326431460771517190893150548229499215350322029536332330582392\
18806567712528926647782037625464558715616413319854776533154457748\
50369951148002019452847630950654803575772277566553803846025187184\
34444574497140925493969286388704593318292908330044401516114387588\
41129568723129083535935666107640185745007715819259946270361339845\
63266376803845196832828240730548739044529176512107067406391527837\
57557358360782528688863949682777531085194899507204378035121581634\
24414088402731389247357737928169297087400188551068409902167210976\
99668535678352198115657924571726602015561676282558489121953241400\
31207429948640258928848640629219636659534812792822670096916525074\
92689877547982499255923044560155940630587612552147776483441652816\
33236765741973747177767093758966792753915098622478083341278699474\
61724291491874192863031534896067586188321251023323955047888297199\
99217044991519287327160933912040296276276242348097165496172742690\
86466569441720773638821952373188913643662294845373908383902122732\
57690268796744633096769122526030738819573331098032907140498720008\
13035742950851348313598383399074414967055732327291982453954045810\
80842325049649761748796838786086458738890864373475302175875704290\
69913688074348037854515150494366271992924434038972072364623933515\
35108523881948862331674561312861919905943354459088929891444774041\
37877258586791658859754564125677939626809742619915779730287028484\
60639819192296728586447064779019114742341835006766442016072934648\
63875973516361673678057437839898835537149537164515633053161142888\
18005648558646358710551291222742512100699868862843079002494001711\
30529624644030648543655285826939709869391484019919363825896807557\
03355972387881865951424806790745995688760042329946947624109661700\
82452571386658548081130928574260460399814489165244566557234765399\
2658988664393075487299560192769248990004510
(1.95 secs, 79012892 bytes)</pre>
</blockquote>
<p>That&#8217;s 1798 digits if I am counting correctly. And here is the verification that <code>(denum.unfn).(fn.enum)</code> is the identity for all numbers up to 10000:</p>
<blockquote>
<pre>&gt; <strong>map (denum . unfn . fn . enum) [0..10000] == [0..10000]</strong>
True
(24.31 secs, 1392197128 bytes)</pre>
</blockquote>
<p>The enumeration of functionals is also handy for trying out Martin&#8217;s functionals &#8220;randomly&#8221;:</p>
<blockquote>
<pre>&gt; <strong>forevery (fn (enum 109809128310938019831032110823012831203922))</strong>
False
(0.17 secs, 4694172 bytes)
&gt; <strong>map (find (fn (enum 100000000000))) [0..15]</strong>
[True,True,True,True,True,True,True,True,True,True,False,True,True,True,True,True]
(1.08 secs, 41505604 bytes)</pre>
</blockquote>
<p>Even though this is slightly impressive and fun, the datatype <code>UCF</code> could be improved to give an even better representation of functionals. For example, the representation of the functional `E_n(alpha) = alpha(n)` is prohibitively large, around `Theta(2^n)`. We should look for a datatype which allows direct access to the `n`-th bit of `alpha`, so to speak. But not today, this post is long enough.</p>
]]></content:encoded>
			<wfw:commentRss>http://math.andrej.com/2009/10/12/constructive-gem-double-exponentials/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Mathematically Structured but not Necessarily Functional Programming</title>
		<link>http://math.andrej.com/2009/05/29/mathematically-structured-but-not-necessarily-functional-programming/</link>
		<comments>http://math.andrej.com/2009/05/29/mathematically-structured-but-not-necessarily-functional-programming/#comments</comments>
		<pubDate>Fri, 29 May 2009 06:16:18 +0000</pubDate>
		<dc:creator>Andrej Bauer</dc:creator>
				<category><![CDATA[Computation]]></category>
		<category><![CDATA[Constructive math]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[RZ]]></category>
		<category><![CDATA[Talks]]></category>

		<guid isPermaLink="false">http://math.andrej.com/?p=217</guid>
		<description><![CDATA[<p>These are the slides and the extended abstract from my MSFP 2008 talk. Apparently, I forgot to publish them online. There is a discussion on the Agda mailing list to which the talk is somewhat relevant, so I am publishing now.</p>
<p>Abstract: Realizability is an interpretation of intuitionistic logic which subsumes the Curry-Howard interpretation of propositions [...]]]></description>
			<content:encoded><![CDATA[<p>These are the slides and the extended abstract from my <a href="http://msfp.org.uk/">MSFP</a> 2008 talk. Apparently, I forgot to publish them online. There is a discussion on the <a href="http://wiki.portal.chalmers.se/agda/">Agda</a> mailing list to which the talk is somewhat relevant, so I am publishing now.</p>
<p><strong>Abstract:</strong> Realizability is an interpretation of intuitionistic logic which subsumes the Curry-Howard interpretation of propositions as types, because it allows the realizers to use computational effects such as non-termination, store and exceptions. Therefore, we can use realizability as a framework for program development and extraction which allows any style of programming, not just the purely functional one that is supported by the Curry-Howard correspondence. In joint work with <a href="http://www.cs.hmc.edu/~stone/">Christopher A. Stone</a> we developed RZ, a tool which uses realizability to translate specifications written in constructive logic into interface code annotated with logical assertions. RZ does not extract code from proofs, but allows any implementation method, from handwritten code to code extracted from proofs by other tools. In our experience, RZ is useful for specification of non-trivial theories. While the use of computational effects does improve efficiency it also makes it difficult to reason about programs and prove their correctness. We demonstrate this fact by considering non-purely functional realizers for a Brouwerian continuity principle.</p>
<p><strong>Download: </strong><a href="/wp-content/uploads/2009/05/msfp2008-slides.pdf">msfp2008-slides.pdf</a>, <a href="/wp-content/uploads/2009/05/msfp2008-abstract.pdf">msfp2008-abstract.pdf</a></p>
]]></content:encoded>
			<wfw:commentRss>http://math.andrej.com/2009/05/29/mathematically-structured-but-not-necessarily-functional-programming/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>On programming language design</title>
		<link>http://math.andrej.com/2009/04/11/on-programming-language-design/</link>
		<comments>http://math.andrej.com/2009/04/11/on-programming-language-design/#comments</comments>
		<pubDate>Sat, 11 Apr 2009 16:29:03 +0000</pubDate>
		<dc:creator>Andrej Bauer</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://math.andrej.com/?p=194</guid>
		<description><![CDATA[<p>In a recent post I claimed that Python&#8217;s lambda construct is broken. This attracted some angry responses by people who thought I was confused about how Python works. Luckily there were also many useful responses from which I learnt. This post is a response to comment 27, which asks me to say more about my [...]]]></description>
			<content:encoded><![CDATA[<p>In a recent post I claimed that <a href="/2009/04/09/pythons-lambda-is-broken/">Python&#8217;s lambda construct is broken</a>. This attracted <a href="/2009/04/09/pythons-lambda-is-broken/#comment-11485">some</a> <a href="/2009/04/09/pythons-lambda-is-broken/#comment-11486">angry</a> <a href="/2009/04/09/pythons-lambda-is-broken/#comment-11499">responses</a> by people who thought I was confused about how Python works. Luckily there were also many useful responses from which I learnt. This post is a response to <a href="/2009/04/09/pythons-lambda-is-broken/#comment-11501">comment 27</a>, which asks me to say more about my calling certain design decisions in Python crazy.</p>
<p><span id="more-194"></span>Language design is like architecture. The architect is bound by the rules of nature, he has to take into account the properties of the building materials, and he must never forget the purpose that the building will serve. Likewise, the designer of a programming language is bound by the theorems of computability theory, he must take into account the properties of the underlying hardware, and he must never forget that the language is used by programmers.</p>
<p>When I teach the theory of programming languages, I tell my students that there is a design principle from which almost everything else follows:</p>
<blockquote><p><em>&#8220;Programmers are just humans: forgetful, lazy, and they make every mistake imaginable.&#8221;</em></p></blockquote>
<p>Therefore, it is the task of the designer to make a programming language which counters these deficiencies. A language must not be too complex, lest the programmer forget half of it. A language must support the programmer&#8217;s laziness by providing lots of useful libraries, and by making it possible to express ideas directly and succinctly. The language must allow good organization of source code, otherwise the programmer will use the copy-paste method. The language must try really hard to catch programming mistakes, especially the mundane ones that happen to everyone all the time. When it finds a mistake, it must point to the true reason for it, preferably with an error message that humans understand.</p>
<p>You will notice that so far I have not said a word about efficiency. If this were the year 1972 we would talk about efficiency first and forget about the programmers, because 37 years ago hardware and processing time were the scarcest resources. Today we live in different times when the most expensive resource is development time. In 1972 it was a <em>good</em> design decision to implement arrays in C so that they did not carry with them information about their lengths (save a couple of bytes on each array), it was a <em>good</em> decision not to check for out-of-bounds errors in array indexing (save a couple of CPU cycles), and it was a <em>good</em> decision not to have garbage collection (it didn&#8217;t work well anyhow). From today&#8217;s point of view all these decisions were horrible mistakes. Buffer overflows, which are a consequence of missing out-of-bounds checks, cost the industry huge amounts of money every year, while lack of automated garbage collection results in memory leaks that cause programs to be unstable.</p>
<p>Of course, even today C might be just the right tool for your specific task. I am not saying that memory efficiency and speed are not important. They are not <em>as important</em> as they used to be. The first objective in a programming language design today should be friendliness to programmers. A lot is known about how to write an optimizing compiler and how to generate efficient code, so usually the design of the language does not prevent generation of efficient compiled or interpreted code.</p>
<p>People do not make bad design decisions because they are evil or stupid. They make them because they judge that the advantages of the decision outweigh the disadvantages. What they often do not see is that they could have achieved the same advantages in a different way, without introducing the disadvantages. Therefore, it is very important to get the order right: <em>first</em> make sure the design avoids the disadvantages, <em>then</em> think about how to get the advantages back.</p>
<p>Let us now apply these principles to several examples.</p>
<h3>Undefined values (NULL, null, undef, None)</h3>
<p>Suppose we want a language with references (pointers in C). The principle tells us that it is a bad idea to allow invalid references because programmers <em>will</em> create them. Indeed, most recently designed languages, say Java and Python, do not allow you to write obviously risky things, such as</p>
<blockquote>
<pre>int *p = (int *)0xabcdef;</pre>
</blockquote>
<p>Unfortunately, many designers have still not learnt that the special <code>NULL</code> pointer or <code>null</code> object is an equally bad idea. Python&#8217;s <code>None</code>, perl&#8217;s <code>undef</code>, and SQL&#8217;s <code>NULL</code> all fall in the same category. I can hear you list lots of advantages of having these. But stick to the principle: <code>NULL</code> is wrong because it causes horrible and tricky mistakes which appear even after the program was tested thoroughly. You cannot introduce <code>NULL</code> into the language and tell the programmer to be careful about it. The programmer is not capable of being careful! There is plenty of evidence to support this sad fact.</p>
<p>Therefore <em>NULL, null, None and undef must go.</em> I shall collectively denote these with Python&#8217;s <code>None</code>. Of course, if we take away None, we must put something else back in. To see what is needed, consider the fact that <code>None</code> is intended as a special constant that signifies &#8220;missing value&#8221;. Problems occur when a given value could be either &#8220;proper&#8221; or &#8220;missing&#8221; and the programmer forgets to consider the case of missing value. The solution is to design the language in such a way that the programmer is always forced to consider both possibilities.</p>
<p>For example, Haskell does this with the datatype <a href="http://en.wikibooks.org/wiki/Haskell/Hierarchical_libraries/Maybe"><code>Maybe</code></a>, which has two kinds of values:</p>
<ul>
<li><code>Nothing</code>, meaning &#8220;missing value&#8221;</li>
<li><code>Just x</code>, meaning &#8220;the value is <code>x</code>&#8220;</li>
</ul>
<p>The <em>only</em> way to use such a value in Haskell is to consider <em>both</em> cases, otherwise the compiler complains. The language is forcing the programmer to do the right thing. Is this annoying? You will probably feel annoyed if you are used to ugly hacks with <code>None</code>, but a bit of experience will quickly convince you that the advantages easily outweigh your tendency for laziness. By the way, Haskell actually supports your laziness. Once you tell it that the type of a value is <code>Maybe</code>, it will find for you all the places where you need to be careful about <code>Nothing</code>. C, Java, Python, and perl stay silent and let you suffer through your own mistaken uses of <code>NULL</code>&#8217;s, <code>null</code>&#8217;s, <code>None</code>&#8217;s, and <code>undef</code>&#8217;s.</p>
<p>Other languages that let you have the data type like Haskell&#8217;s <code>Maybe</code> are ML and Ocaml because they have <a href="http://en.wikipedia.org/wiki/Sum_type">sum types</a>. Pascal, Modula-2 and C have broken sum types because they require the programmer to handle the tag by hand.</p>
<h3>Everything is an object (or list, or array)</h3>
<p>Many languages are advertised as &#8220;simple&#8221; because in them everything is expressed with just a couple of basic concepts. Lisp and scheme programmers proudly represent all sorts of data with conses and lists. Fortran programmers implement linked lists and trees with arrays. In Java and Python &#8220;everything is an object&#8221;, more or less.</p>
<p>It is good to have a simple language, but it is not good to sacrifice its expressiveness to the point where most of the time the programmer has to encode the concepts that he really needs indirectly with those available in the language. Programmers cannot do such things reliably, and the compiler cannot help them with the task because it does not know what is in programmer&#8217;s head.</p>
<p>Let us look at a typical example in scheme. Suppose we would like to represent binary trees in which the nodes are labeled with integers. In scheme we might do this by representing the empty tree as <code>()</code>, and use a three-element list <code>(k l r)</code> to represent a tree whose root is labeled by <code>k</code>, the left subtree is <code>l</code>, and the right subtree is <code>r</code>. A <a href="http://www.google.si/search?q=scheme+binary+tree">quick search on Google</a> shows that this is a popular way of implementing trees in scheme. It&#8217;s simple, it&#8217;s cool, it&#8217;s easy to explain to the students, but scheme will have no idea whatsoever what you&#8217;re doing. There are a number of trivial mistakes which can be made with such a representation, and scheme won&#8217;t detect them (at best you will get a runtime error): you might write <code>(l k r)</code> instead of <code>(k l r)</code>, you might mistakenly pass a four-element list to a function expecting a tree, you might mistakenly think that the integer <code>42</code> is a valid representation of the tree <code>(42 () ())</code>, you might mistakenly try to compute the left subtree of the empty tree, etc. And remember, the programmer <em>will</em> make all these mistakes.</p>
<p>With objects the situation is somewhat better. In Java we would define a class Tree with three attributes <code>root</code>, <code>left</code>, and <code>right</code>. It will be impossible to build a tree with a missing attribute, or too many attributes. But we will hit another problem: how to represent the empty tree? There are several choices none of which is ideal:</p>
<ol>
<li>the empty tree is <code>null</code>: this is the worst solution, as any Java programmer knows</li>
<li>we define a class <code>Tree</code> and subclasses <code>EmptyTree</code> and <code>NodeTree </code>represent the two different kinds of tree</li>
<li>we add a fourth attribute <code>empty</code> of type boolean which tells us whether the tree is empty</li>
</ol>
<p>There are probably other options. The first solution is horrible, as every Java programmer knows, because it leads to many <code>NullPointerExceptions</code>. The second solution is probably the most &#8220;object-orientedly correct&#8221; but people find it impractical, as it spreads code around in two classes. When I taught java I lectured the third solution, but that one has the big disadvantage that the programmer is responsible for checking every time whether a tree is empty or not.</p>
<p>A decent programming language should help with the following common problems regarding binary trees:</p>
<ol>
<li>Prevent the construction of an invalid tree, such as one with missing parts, or dangling pointers.</li>
<li>Prevent <em>at compile time</em> access to a component which is not there. For example, the compiler should detect the fact that the programmer is trying to access the left subtree of the empty tree.</li>
<li>Make sure the programmer never forgets to consider both possibilities&#8211;the empty tree and the non-empty tree.</li>
</ol>
<p>The above scheme representation does not help with the first problem. A C implementation with pointers would allow dangling pointers. An object-oriented solution typically won&#8217;t help with the second and the third problems.</p>
<p>You might wonder what it is that I want. The answer is that the programming language should have built-in <em>inductive data types</em>, because that&#8217;s what binary trees are. In Haskell, which has inductive data types, trees are defined directly in terms of their structure:</p>
<blockquote>
<pre>data Tree = Empty | Node Int Tree Tree</pre>
</blockquote>
<p>This expresses the definition of trees <em>directly</em>: a tree is either empty or a node composed of an integer and two trees. Haskell will be able to catch all the common problems listed above. Other languages supporting this sort of definition are ML, Ocaml, F#, and interestingly Visual Prolog (I am told by Wikipedia).</p>
<p>We might ask for more. Suppose we wanted to implement <a href="http://en.wikipedia.org/wiki/Binary_search_tree">binary search trees</a>. Then we would require that the left subtree only contains nodes that are smaller than the root, and the right subtree only nodes that are larger than the root. Can a programming language be designed so that this property is guaranteed? Yes, for example the compiler could insert suitable checks into the code so that anomalies are detected during execution as soon as they occur. This might be nice for debugging purposes, but what is production code supposed to do if it discovers an anomalous data structure during its execution? Ignore it? Raise an exception? It is much more useful to know <em>before</em> the program is run that the data structure will never be corrupted. Here we hit against a law of nature: there is no algorithm that would analyze an arbitrary piece of code and determine whether it will only produce valid search trees. It is a fact of life. If you really want to check that your programs are correct you will have to help the compiler. There are excellent tools for doing that, such as <a href="http://coq.inria.fr/">Coq</a> and <a href="http://wiki.portal.chalmers.se/agda/">Agda</a>&#8211;have a look to see how programmers might develop their code in the future.</p>
<h3>Confusing definitions and variables</h3>
<p>A <em>definition</em> binds an identifier to a particular <em>fixed</em> value. A <em>variable</em> or a <em>mutable value</em> is a memory location which holds a value that can be read and changed. These two notions should not be confused. Unfortunately, traditional programming languages only provide variables, so many programmers don&#8217;t even understand what definitions are. Java tries to fix this with the <a href="http://en.wikipedia.org/wiki/Final_(Java)">final</a> declaration, and C++ with the const declaration, but these are not used by programmers as much as they could be (which is a typical sign of dubious design decisions).</p>
<p>Using variables instead of definitions is wrong for a number of reasons. First, if the compiler knows which identifiers are bound to immutable values it can optimize the code better. It can, for example, decide to store the value in a register, or to keep around several copies without worrying about synchronization between them (think threaded applications). Second, if we allow the programmer to change a value which is supposed to be constant, then he will do so.</p>
<p>If you observe how variables are typically used, you will see several distinct uses:</p>
<ul>
<li>often a variable is only assigned to once and is used as an (immutable) definition</li>
<li>a variable in a loop or list comprehension ranges over the elements of a list, or a collection of objects</li>
<li>a variable stores the current state and is genuinely mutable</li>
</ul>
<p>Should loop counters be mutable? I think not. Code that changes the loop counter in the body of the loop is confusing and error prone. If you want to fiddle with counters, use the while loop instead. So in two out of three cases we want our variables to be immutable, but the popular programming languages only give us variables. That&#8217;s silly. We should design the language so that the <em>default</em> case is an immutable value. If the programmer wants a mutable value, he should say so explicitly. This is just the opposite of what Java and C++ do. An example of a language that is designed this way is <a href="http://en.wikipedia.org/wiki/Standard_ML">ML</a> and <a href="http://www.ocaml.org/">ocaml</a>. In Haskell you have to jump through hoops to get mutable values (now I am going to hear it from a monad aficionado, please spare me an unnecessary burst of anger).</p>
<h3>Out of scope variables</h3>
<p>I thought I would not have to explain why undefined identifiers are a bad a idea, but the reader in <a href="/2009/04/09/pythons-lambda-is-broken/#comment-11501">comment 27</a> explicitly asked about this.</p>
<p>If a programmer refers to an undefined name then an error should be reported. Concretely, I claimed that Python should complain about the following definition:</p>
<blockquote>
<pre>def f(n): return i + n</pre>
</blockquote>
<p>What is <code>i</code>? Pythonists will quickly point out that <code>i</code> will be defined later, and how deferred definitions are useful because they allows us to define mutually recursive functions. Indeed, Java and Haskell also accept mutually recursive definitions. But unlike Python they make sure that nothing is missing at the time of definition, whereas Python will only complain when the above function <code>f</code> is used. To be honest, Python kindly displays the correct error message showing that the trouble is with the definition of <code>f</code>. But why should this be a runtime error when the mistake can easily be detected at compile time? Actually, this question leads to a more general question, which I consider next.</p>
<h3>When should mistakes be discovered?</h3>
<p>Should programming bugs be discovered by the programmer or by the user? The answer seems pretty clear. Therefore, a language should be designed so that as many programming errors as possible are discovered early on, that is <em>before</em> the program is sent to the user. In fact, in order to speed up development (remember that the development time is expensive) the programmer should be told about errors without having to run the program and directing its execution to the place where the latest code change actually gets executed.</p>
<p>This philosophy leads to the design of <em>statically</em> checked languages. A typical feature of such a language is that all the types are known at compile time. In contrast, a dynamically typed languages checks the types during runtime. Java, Haskell and ocaml are of the former kind, scheme, javascript and Python of the latter.</p>
<p>There are situations in which a statically checked language is better, for example if you&#8217;re writing a program that will control a laser during eye surgery. But there are also situations in which maximum flexibility is required of a program, for example programs that are embedded in web pages. The web as we know it would not exist if every javascript error caused the browser to reject the entire web page (try finding a page on a major web site that does not have any javascript errors).</p>
<p>Let me also point out that <em>testing</em> cannot replace good language design. Testing is very important, but it should be used to discover problems that cannot be discovered earlier in the development cycle.</p>
<p>I used to think that statically checked languages are better for teaching because they prevent the students from doing obviously stupid things. About two years ago I changed my mind. The students learn much better by doing stupid things than by being told by an oppressive compiler that their programs are stupid. So this year I switched to Python. The students are happier, and so am I (because I don&#8217;t have to explain that code must be properly indented). Python does not whine all the time. Instead it lets them explore the possibilities, and by discovering which ones crash their programs they seem to understand better how the machine works.</p>
]]></content:encoded>
			<wfw:commentRss>http://math.andrej.com/2009/04/11/on-programming-language-design/feed/</wfw:commentRss>
		<slash:comments>59</slash:comments>
		</item>
	</channel>
</rss>
