ATS -- unleashing the potential of types!


  • What is ATS?
  • Acknowledgments
  • Download and Installation: The current stable release is ats-lang-anairiats-0.1.4 (1.4MB)
  • Some Simple ATS Programs

  • What is ATS?

    ATS is a programming language with a highly expressive type system rooted in the framework Applied Type System. In particular, both dependent types and linear types are available in ATS. The current implementation of ATS (ATS/Anairiats) is written in ATS itself. It can be as efficient as C/C++ (see The Computer Language Benchmarks Game for concrete evidence) and supports a variety of programming paradigms that include:

    • Functional programming. While ATS is primarily a language based on eager (aka. call-by-value) evaluation, it also supports lazy (aka. call-by-need) evaluation. The availability of linear types in ATS can often make functional programs in ATS not only run with surprisingly high efficiency (when compared to C) but also run with surprisingly small (memory) footprint (when compared to C as well).

    • Imperative programming. The novel and unique approach to imperative programming in ATS is firmly rooted in the paradigm of programming with theorem proving. While features considered dangerous in other languages (e.g., explicit pointer arithmetic and explicit memory allocation/deallocation) are allowed in ATS, the type system of ATS is still able to guarantee that no run-time errors can occur that may lead to memory corruption.

    • Concurrent programming. ATS, equipped with a multicore-safe implementation of garbage collection, can support multithreaded programming through the use of pthreads. There is also high-level support in ATS for parallel let-binding, which provides a simple and effective means to constructing programs that can take advantage of multicore architectures.

    • Modular programming. The module system of ATS is largely infuenced by that of Modula-3, which is both simple and general as well as effective in supporting large scale programming.

    In addition, ATS contains a component ATS/LF that supports a form of (interactive) theorem proving, where proofs are constructed as total functions. With this component, ATS advocates a programming style that combines programming with theorem proving. Furthermore, this component may be used as a logical framework to encode various deduction systems and their (meta-)properties.

  • Acknowledgments

    The development of ATS has been funded in part by National Science Foundation under the grants no. CCR-0081316/CCR-0224244, no. CCR-0092703/0229480, no. CNS-0202067 and no. CCF-0702665. As always, any opinions, findings, and conclusions or recommendations expressed here are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.

    Many people worked on ATS in the past. The names of some of these people are included in the following list:

    Chiyan Chen, Sa Cui, Matthew Danish, Kevin Donnelly, Rick Lavoie, Likai Liu, Michel Machado, Rui Shi, Hongwei Xi, Dengping Zhu

  • Download and Installation

    ATS is Open Source and Free Software, and it is freely available under the GNU GENERAL PUBLIC LICENSE version 3 (GPL 3.0) as is published by the Free Software Foundation. The current implementation of ATS is given the name ATS/Anairiats or simply Anairiats.

    Requirements

    In order to install ATS, the following requirements need to be met:
  • Operating System requirement: ATS is supported under the following operating systems:
    • Linux
    • Windows with Cygwin
    • MacOS X (currently no GC support for multithreading)
    • SunOS (currently no GC support for multithreading)
    • BSD Unix (currently no GC support for multithreading)
  • Programming Language requirement: GNU C Compiler (GCC).
  • We plan to port ATS to other platforms in the future. If you have succeeded in porting ATS to a platform not listed here, please drop us a note.

    The GMP library (libgmp.a), which is in general included in a GNU/Linux distribution, is currently optional and it may be required for installing a release of ATS in the future. Please see http://gmplib.org for more details on GMP.

    Installation from a precompiled package

    This installation method currently only supports the following platforms:

    • Linux on i386 (x86-32)
    • Linux on AMD64 (x86-64)
    • SunOS on UltraSparc

    Please first download a compressed tarball containing a precompiled release of ATS from the following site that suits your platform:

    http://sourceforge.net/projects/ats-lang/download

    (METHOD 1) You can untar the tarball in the root directory "/" and then set the shell environment variable ATSHOME to "/usr/share/atshome". This method most likely requires root access.

    (METHOD 2) You can untar the tarball in the directory "/tmp", and then move the directory "/tmp/usr/share/atshome" into a directory of your choice, say, "FOO", and then set the environment variables ATSHOME and ATSHOMERELOC to "FOO/atshome" and "/usr/share/atshome", repectively. In addition, you need to put "$ATSHOME/bin" on your execution path or create symbolic links to the executables $ATSHOME/bin/atscc and $ATSHOME/bin/atsopt in a directory that is already on your execution path.

    Installation through source code compilation

  • Step 1:

    After downloading a compressed tarball containing a release of ATS from the following site:

    http://sourceforge.net/projects/ats-lang/download

    please untar it in a directory, say "FOO", of your choice. This, for instance, can be done by executing the following command line:

    tar -zvxf ATS.tar.gz 
    All the files and directories extracted from the tarball are now in the directory "FOO/ATS".
  • Step 2:

    Please set the shell environment variable ATSHOME to be "FOO/ATS" (not "FOO/ATS/"). For instance, this can be done by executing the following command line in BASH:
    ATSHOME=FOO/ATS; export ATSHOME
    or the following command line in CSH/TCSH:
    setenv ATSHOME FOO/ATS
    You may want to put this command in a file (e.g., .bashrc or .cshrc) that is executed each time when a shell is started.

    Also, you need to set the environment variable ATSHOMERELOC to "/usr/share/atshome" (or whatever value you prefer) if you intend to change the value of ATSHOME later. For instance, this is often needed if you want to build a precompiled package of ATS for distribution.

  • Step 3:

    You can now go into the directory "FOO/ATS" and execute
    make all
    This generates executables "atscc" and "atsopt" in the directory "FOO/ATS/bin", which are the commands for compiling ATS programs. Also, this generates a library file "libats.a" in the directory "FOO/ATS/ccomp/lib".
  • Step 4

    Lastly, you need to create symbolic links for "atscc" and "atsopt" in a directory (e.g., "/usr/bin" if you have root access) that is on your execution path, or you may simply put the directory "FOO/ATS/bin" on your execution path. The latter can be done in BASH as follows:
    PATH=${PATH}:${ATSHOME}/bin; export PATH
    or in CSH/TCSH as follows:
    setenv PATH ${PATH}:${ATSHOME}/bin
    If you do so, please consider putting this command in a file (e.g., .bashrc or .cshrc) that is executed each time when a shell is started.
  • Installation through bootstrapping

    This installation method is probably the best if you would like to keep abreast of the development of ATS. Please find more details here.
  • Some Simple ATS Programs

    Let us now construct and compile some simple ATS programs.

    Hello, world!

    In a file named HelloWorld.dats, we write the following lines of code
    // compilation command:
    //   atscc -o HelloWorld HelloWorld.dats
    
    implement main () = begin
      print ("Hello, world!"); print_newline ()
    end
    
    By executing the following command line, we produce an excutable file named "HelloWorld":
    atscc -o HelloWorld HelloWorld.dats
    What happens here is that atscc first compiles HelloWorld.dats into HelloWorld_dats.c, which is then compiled by gcc to produce "HelloWorld". By running "HelloWorld", we can see the following line on the standard output:
    Hello, world!

    Factorial (version 1)

    A simple recursive function fact1 is defined as follows to compute factorials.
    // [fun] declares a recursive function
    fun fact1 (x: int): int = if x > 0 then x * fact1 (x-1) else 1
    
    The following code passes an integer read from the standard input to the function fact1 and then prints the result returned from fact1 onto the standard output.
    // [fn] declares a non-recursive function; it is fine to replace [fn] with [fun]
    // [@(...)] is used in ATS to group arguments for functions of variable arguments
    fn fact1_usage (cmd: string): void =
      prerrf ("Usage: %s [integer]\n", @(cmd)) // print an error message
    
    implement main (argc, argv) =
      if argc >= 2 then let
        val n = int1_of argv.[1] // turning a string into an integer
        val res = fact1 n
      in
        printf ("factorial of %i = %i\n", @(n, res))
      end else begin
        fact1_usage (argv.[0]); exit (1)
      end
    
    Note that the function exit is given the following type:
    // [a:viewt@ype] means that [a] can be a linear type of any size
    fun exit : {a:viewt@ype} int -> a
    
    Also note that the type void should not be confused with the type unit in languages like SML and OCaml; the former is of size 0 while the latter is of size 1 (word).

    The entire code for this example is available here.

    Factorial (version 2)

    Let us now see an example involving dependent types. In ATS, int is a static constant of the following sort:
    int -> type
    Note that the symbol int is overloaded: it is both a static constant and a sort. Given an integer i (of sort int), int(i) is a singleton type containing only the integer i. So int is often called a type constructor. We now define a type constant Int as follows:
    typedef Int = [n:int] int n // type for integers
    
    We use the syntax [n:int] to existentially quantify over some variable n of sort int, that is, n ranging over integers. We define the type for natural number as follows:
    typedef Nat = [n:int | n >= 0] int n // type for natural numbers
    
    where the syntax [n:int | n >= 0] represents existential quantification over some variable n of sort int that satisfies n >= 0.

    The factorial function can be implemented as follows:

    fun fact2 {n:nat} (x: int n): Nat = if x > 0 then x nmul fact2 (x-1) else 1
    
    The type assigned to fact2 indicates that the function returns a natural number when applied to a natural number. It causes a type error if fact2 is applied to a negative integer. The function nmul (infix) is assumed to be of the following type:
    (Nat, Nat) -> Nat
    That is, nmul returns a natural number when applied to two natural numbers. The following code indicates the necessity to check that an integer read from the standard input is nonngative when fact2 is called on it.
    // [fn] declares a non-recursive function
    // [@(...)] is used in ATS to group arguments for functions of variable arguments
    fn fact2_usage (cmd: string): void =
      prerrf ("Usage: %s [integer]\n", @(cmd)) // print an error message
    
    implement main (argc, argv) =
      if argc >= 2 then let
        val n = int1_of argv.[1] // turning a string into an integer
        val () = assert_errmsg
          (n >= 0, "The integer argument needs to be nonnegative.\n")
        val res = fact2 n
      in
        printf ("factorial of %i = %i\n", @(n, res))
      end else begin
        fact2_usage (argv.[0]); exit (1)
      end
    
    The entire code for this example is available here. One may want to see what happens to typechecking if the call to assert_errmsg in the code is deleted.

    Factorial (version 3)

    If you are not afraid of being overwhelmed at this moment, please find an implementation of the factorial function here that bears the signature of ATS: programming with theorem proving. This is an implementation of the factorial function whose correctness is formally verified in the type system of ATS.

    List Quicksort

    This one is for program verification enthusiasts: An implementation of list quicksort is given here that guarantees solely based on its type that the implmentation is terminating and the output list it returns is always a sorted permutation of its input list. This is considered a milestone example in the development of ATS.

    More Examples

    Please find more, more advanced and larger, examples here.

  • Resources for Programming in ATS

    Please follow the link to find the User's Guide on ATS/Anairiats, an Emacs mode for ATS, a variety of contributed code, and more.


  • This page is maintained by Hongwei Xi. As always, your comments are welcome.


    SourceForge.net Logo