ATS (programming language): Difference between revisions
Australaves (talk | contribs) mNo edit summary |
|||
(36 intermediate revisions by 22 users not shown) | |||
Line 1: | Line 1: | ||
{{Short description|Programming language}} |
|||
{{primary sources|date=March 2018}} |
|||
{{Multiple issues| |
|||
{{Primary sources|date=March 2018}} |
|||
{{Manual|date=February 2020}} |
|||
{{Technical|date=September 2020}} |
|||
}} |
|||
{{Infobox programming language |
{{Infobox programming language |
||
| name |
| name = ATS |
||
| logo |
| logo = The ATS Logo.svg |
||
| |
| paradigms = [[Comparison of multi-paradigm programming languages|multi-paradigm]]: [[Functional programming|functional]], [[Imperative programming|imperative]], [[Object-oriented programming|object-oriented]], [[Concurrent computing|concurrent]], [[Modular programming|modular]] |
||
| family = [[ML (programming language)|ML]]: [[Caml]]: [[OCaml]]: [[Dependent ML]] |
|||
| year = |
|||
| released = {{Start date and age|2006}} |
|||
| designer = [[Hongwei Xi]] at [[Boston University]] |
|||
| designer = Hongwei Xi |
|||
| developer = |
|||
| developer = [[Boston University]] |
|||
| latest release version = ATS2-0.3.13<ref>{{cite web |url=https://groups.google.com/forum/#!topic/ats-lang-users/IrwY6Blw3Tg |title=[ats-lang-users] ATS2-0.3.13 released |author=ats-lang |website=ats-lang-users |date=16 Feb 2019 |access-date=16 Feb 2019}}</ref> |
|||
| latest release version = ATS2-0.4.2<ref>{{cite web |url=https://groups.google.com/g/ats-lang-users/c/ZlSW70S525Y |title=[ats-lang-users] ATS2-0.4.2 released |last=Xi |first=Hongwei |website=ats-lang-users |date=14 November 2020 |access-date=17 November 2020}}</ref> |
|||
| latest release date = {{Start date and age|2019|02|16}} |
|||
| latest release date = {{Start date and age|2020|11|14}} |
|||
| typing = [[Static typing|static]] |
|||
| typing = [[Static typing|static]], [[Dependent type|dependent]] |
|||
| implementations = |
|||
| implementations = |
|||
| dialects = |
|||
| dialects = |
|||
| influenced_by = [[Dependent ML]], [[ML (programming language)|ML]], [[OCaml]], [[C++]] |
|||
| influenced |
| influenced by = [[Dependent ML]], [[ML (programming language)|ML]], [[OCaml]], [[C++]] |
||
| influenced = |
|||
| operating system = |
|||
| operating system = |
|||
| file ext = .sats, .dats, .cats, hats. |
|||
| file ext = .sats, .dats, .hats |
|||
| license = [[GNU General Public License|GPLv3]] |
|||
| license = [[GNU General Public License|GPLv3]] |
|||
| website = [http://www.ats-lang.org/ http://www.ats-lang.org/] |
|||
| website = {{URL|www.ats-lang.org}} |
|||
}} |
}} |
||
'''ATS (Applied Type System |
In computing, '''ATS''' ('''Applied Type System''') is a [[Comparison of multi-paradigm programming languages|multi-paradigm]], [[General-purpose programming language|general-purpose]], [[High-level programming language|high-level]], [[Functional programming|functional]] [[programming language]]. It is a [[Dialect (computing)|dialect]] of the programming language [[ML (programming language)|ML]], designed by Hongwei Xi to unify [[computer programming]] with [[formal specification]]. ATS has support for combining [[theorem proving]] with practical programming through the use of advanced [[type system]]s.<ref name="ats-lang.org">{{Cite web |url=http://www.ats-lang.org/MYDATA/CPwTP-icfp05.pdf |title=Combining Programming with Theorem Proving |access-date=2014-11-18 |archive-date=2014-11-29 |archive-url=https://web.archive.org/web/20141129050328/http://www.ats-lang.org/MYDATA/CPwTP-icfp05.pdf |url-status=dead}}</ref> A past version of [[The Computer Language Benchmarks Game]] has demonstrated that the performance of ATS is comparable to that of the languages [[C (programming language)|C]] and [[C++]].<ref>[https://web.archive.org/web/20121218042116/http://shootout.alioth.debian.org/u64/ats.php ATS benchmarks | Computer Language Benchmarks Game] (web archive)</ref> By using theorem proving and strict type checking, the compiler can detect and prove that its implemented functions are not susceptible to bugs such as [[division by zero]], [[memory leak]]s, [[buffer overflow]], and other forms of [[memory corruption]] by verifying [[pointer arithmetic]] and [[reference counting]] before the program compiles. Also, by using the integrated theorem-proving system of ATS (ATS/LF), the programmer may make use of static constructs that are intertwined with the operative code to prove that a function conforms to its specification. |
||
ATS consists of a static component and a dynamic component. The static component is used for handling types, whereas the dynamic component is used for programs. While ATS primarily relies on a call-by-value functional language at its core, it possesses the ability to accommodate diverse [[programming paradigm]]s, such as [[Functional programming|functional]], [[Imperative programming|imperative]], [[Object-oriented programming|object-oriented]], [[Concurrent computing|concurrent]], and [[Modular programming|modular]]. |
|||
== History == |
== History == |
||
According to the author, ATS was inspired by Martin-Löf's [[Intuitionistic type theory|constructive type theory]], which was originally developed for the purpose of establishing a foundation for mathematics. Xi designed ATS “in an attempt to combine specification and implementation into a single programming language.”<ref>{{Cite web |title=Introduction to Programming in ATS |url=https://ats-lang.github.io/DOCUMENT/INT2PROGINATS/HTML/INT2PROGINATS-BOOK-onechunk.html |access-date=2024-02-23 |website=ats-lang.github.io}}</ref> |
|||
ATS is derived mostly from the [[ML (programming language)|ML]] and [[OCaml]] programming languages. An earlier language, [[Dependent ML]], by the same author has been incorporated by the language. |
|||
ATS is derived mostly from the languages [[ML (programming language)|ML]] and [[OCaml]]. An earlier language, [[Dependent ML]], by the same author has been incorporated into ATS. |
|||
The first implementation, ATS/Proto (ATS0), was written in OCaml and was released in 2006. This was the pre-first edition of ATS and is no longer maintained. A year later, ATS/Geizella, the first implementation of ATS1, was released. This version was also written in OCaml and is no longer used actively.<ref name=":0">{{Cite web |title=ATS-PL-SYS |url=https://www.cs.bu.edu/~hwxi/atslangweb/Implements.html |access-date=2024-02-23 |website=www.cs.bu.edu}}</ref> |
|||
The second version of ATS1, ATS/Anairiats, released in 2008, was a major milestone in the development of the language, as the language was able to [[Bootstrapping (compilers)|bootstrap]] itself. This version was written almost completely in ATS1. The current version, ATS/Postiats (ATS2) was released in 2013. Like its predecessor, this version is also almost entirely written in ATS1. The most recently released version is ATS2-0.4.2.<ref name=":0"/> |
|||
== Future == |
|||
{{As of|2024}}, ATS is used mostly for research; less than 200 [[GitHub]] repositories contain code written in ATS. This is far less than other functional languages, such as OCaml and Standard ML, which have over 16,000 and 3,000 repositories, respectively. This is likely due to the steep learning associated with ATS, which is present because of the language's use of [[dependent type]]-checking and template instance resolution. These features usually require the use of explicit [[Quantifier (logic)|quantifiers]], which demand further learning.<ref name=":1">{{Cite web |last=Xi |first=Hongwei |date=2024-02-17 |url=https://github.com/githwxi/ATS-Xanadu |title=githwxi/ATS-Xanadu |website=GitHub |access-date=2024-02-23}}</ref> |
|||
{{As of|2024}}, ATS/Xanadu (ATS3) is being developed actively in ATS2, with the hope of reducing the learning needed by two main improvements: |
|||
* Adding an extra layer to ATS2 to support ML-like [[Algebraic data type|algebraic type]]-checking |
|||
* Type-based [[metaprogramming]] using algebraic types only<ref name=":1"/> |
|||
With these improvements, Xi hopes for ATS to become much more accessible and easier to learn. The main goal of ATS3 is to transform ATS from a language mainly used for research, into one strong enough for large-scale industrial software development.<ref name=":0"/> |
|||
The latest version of ATS1 (Anairiats) was released as v0.2.12 on 2015-01-20.<ref>https://sourceforge.net/projects/ats-lang/files/ats-lang/</ref> The first version of ATS2 (Postiats) was released in September 2013.<ref>https://github.com/githwxi/ATS-Postiats/commit/30fd556e649745f735eafbdace54373fa163862e</ref> |
|||
== Theorem proving == |
== Theorem proving == |
||
The |
The main focus of ATS is to support [[formal verification]] via [[automated theorem proving]], combined with practical programming.<ref name="ats-lang.org"/> Theorem proving can prove, for example, that an implemented function produces no memory leaks. It can also prevent other bugs that might otherwise be found only during testing. It incorporates a system similar to those of [[proof assistant]]s which usually only aim to verify mathematical proofs—except ATS uses this ability to prove that the implementations of its functions operate correctly, and produce the expected output. |
||
As a simple example, in a function using division, the programmer may prove that the divisor will never equal zero, preventing a [[division by zero]] error. Let's say, the divisor 'X' was computed as 5 times the length of list 'A'. |
As a simple example, in a function using division, the programmer may prove that the divisor will never equal zero, preventing a [[division by zero]] error. Let's say, the divisor 'X' was computed as 5 times the length of list 'A'. One can prove, that in the case of a non-empty list, 'X' is non-zero, since 'X' is the product of two non-zero numbers (5 and the length of 'A'). A more practical example would be proving through [[reference counting]] that the retain count on an allocated block of memory is being counted correctly for each pointer. Then one can know, and quite literally prove, that the object will not be deallocated prematurely, and that [[memory leak]]s will not occur. |
||
The benefit of the ATS system is that since all theorem proving occurs strictly within the compiler, it has no effect on the speed of the executable program. ATS code is often harder to compile than standard [[C (programming language)|C]] code, but once it compiles |
The benefit of the ATS system is that since all theorem proving occurs strictly within the compiler, it has no effect on the speed of the executable program. ATS code is often harder to compile than standard [[C (programming language)|C]] code, but once it compiles, it is certain that it is running correctly to the degree specified by the proofs (assuming the compiler and runtime system are correct). |
||
In ATS proofs are separate from implementation, so it is possible to implement a function without proving it if |
In ATS proofs are separate from implementation, so it is possible to implement a function without proving it, if desired. |
||
== Data representation == |
== Data representation == |
||
According to the author |
According to the author, ATS's efficiency<ref>[https://www.reddit.com/r/programming/comments/72hmw/language_shootout_ats_is_the_new_top_gunslinger/ Discussion about the language's efficiency (Language Shootout: ATS is the new top gunslinger. Beats C++.)]</ref> is largely due to the way that data is represented in the language and [[Tail recursion|tail-call optimizations]] (which are generally important for the efficiency of functional languages). Data can be stored in a flat or unboxed representation rather than a boxed representation. |
||
== An introductory case == |
== Theorem proving: An introductory case == |
||
=== Propositions === |
=== Propositions === |
||
<code>dataprop</code> expresses ''[[Predicate (mathematical logic)|predicates]]'' as algebraic |
<code>dataprop</code> expresses ''[[Predicate (mathematical logic)|predicates]]'' as [[algebraic type]]s. |
||
Predicates in pseudo‑code somewhat similar to ATS source (see below for valid ATS source): |
Predicates in pseudo‑code somewhat similar to ATS source (see below for valid ATS source): |
||
Line 56: | Line 77: | ||
In ATS code: |
In ATS code: |
||
<syntaxhighlight lang="cpp"> |
|||
dataprop FACT (int, int) = |
|||
| FACTbas (0, 1) |
| FACTbas (0, 1) // basic case: FACT(0, 1) |
||
// inductive case |
| {n:int | n > 0} {r,r1:int} // inductive case |
||
FACTind (n, r) of (FACT (n-1, r1), MUL (n, r1, r)) |
|||
</syntaxhighlight> |
|||
where FACT (int, int) is a proof type |
where FACT (int, int) is a proof type |
||
Line 67: | Line 89: | ||
Non tail-recursive factorial with proposition or "[[Theorem]]" proving through the construction ''dataprop''. |
Non tail-recursive factorial with proposition or "[[Theorem]]" proving through the construction ''dataprop''. |
||
The evaluation of fact1(n-1) returns a pair (proof_n_minus_1 | result_of_n_minus_1) which is used in the calculation of fact1(n). The proofs express the predicates of the proposition. |
The evaluation of {{code|fact1(n-1)}} returns a pair <code>(proof_n_minus_1 | result_of_n_minus_1)</code> which is used in the calculation of {{code|fact1(n)}}. The proofs express the predicates of the proposition. |
||
==== Part 1 (algorithm and propositions) ==== |
==== Part 1 (algorithm and propositions) ==== |
||
<syntaxhighlight lang="ocaml"> |
|||
[FACT (n, r)] implies [fact (n) = r] |
[FACT (n, r)] implies [fact (n) = r] |
||
[MUL (n, m, prod)] implies [n * m = prod] |
[MUL (n, m, prod)] implies [n * m = prod] |
||
Line 76: | Line 98: | ||
FACT (0, 1) |
FACT (0, 1) |
||
FACT (n, r) iff FACT (n-1, r1) and MUL (n, r1, r) forall n > 0 |
FACT (n, r) iff FACT (n-1, r1) and MUL (n, r1, r) forall n > 0 |
||
</syntaxhighlight> |
|||
To remember: |
To remember: |
||
Line 83: | Line 105: | ||
(... | ...) (proof | value) |
(... | ...) (proof | value) |
||
@(...) flat tuple or variadic function parameters tuple |
@(...) flat tuple or variadic function parameters tuple |
||
.<...>. termination metric<ref> |
.<...>. termination metric<ref>{{Cite web |url=https://www.cs.bu.edu/~hwxi/ATS/TUTORIAL/contents/termination-metrics.html |title=Termination metrics |access-date=2017-05-20 |archive-date=2016-10-18 |archive-url=https://web.archive.org/web/20161018010907/http://www.cs.bu.edu/~hwxi/ATS/TUTORIAL/contents/termination-metrics.html |url-status=dead}}</ref> |
||
<syntaxhighlight lang="ocaml"> |
<syntaxhighlight lang="ocaml"> |
||
#include "share/atspre_staload.hats" |
#include "share/atspre_staload.hats" |
||
dataprop |
dataprop FACT (int, int) = |
||
| FACTbas (0, 1) of () // basic case |
|||
FACT (int, int) = |
|||
| {n:nat}{r:int} // inductive case |
|||
(* basic case: *) |
|||
| FACTbas (0, 1) of () |
|||
(* inductive case: *) |
|||
| {n:nat}{r:int} |
|||
FACTind (n+1, (n+1)*r) of (FACT (n, r)) |
FACTind (n+1, (n+1)*r) of (FACT (n, r)) |
||
Line 100: | Line 119: | ||
The function signature below says: |
The function signature below says: |
||
forall n:nat, exists r:int where fact( num: int(n)) returns (FACT (n, r) | int(r)) *) |
forall n:nat, exists r:int where fact( num: int(n)) returns (FACT (n, r) | int(r)) *) |
||
fun |
|||
fact{n:nat} .<n>. |
fun fact{n:nat} .<n>. (n: int (n)) : [r:int] (FACT (n, r) | int(r)) = |
||
( |
|||
n: int (n) |
|||
) : [r:int] (FACT (n, r) | int(r)) = |
|||
( |
( |
||
ifcase |
|||
if n > 0 |
|||
| n > 0 => ((FACTind(pf1) | n * r1)) where |
|||
then let |
|||
{ |
|||
val (pf1 | r1) = fact (n-1) in (FACTind(pf1) | n * r1) |
|||
val (pf1 | r1) = fact (n-1) |
|||
end // end of [then] |
|||
} |
|||
else (FACTbas() | 1) |
|||
| _(*else*) => (FACTbas() | 1) |
|||
) |
) |
||
</syntaxhighlight> |
</syntaxhighlight> |
||
Line 117: | Line 134: | ||
<syntaxhighlight lang="ocaml"> |
<syntaxhighlight lang="ocaml"> |
||
implement |
implement main0 (argc, argv) = |
||
main0 (argc, argv) = |
|||
{ |
{ |
||
val () = if (argc != 2) then prerrln! ("Usage: ", argv[0], " <integer>") |
|||
// |
|||
val () = |
|||
if (argc != 2) |
|||
then prerrln! ("Usage: ", argv[0], " <integer>") |
|||
// |
|||
val () = assert (argc >= 2) |
|||
val n0 = g0string2int (argv[1]) |
|||
val n0 = g1ofg0 (n0) |
|||
val () = assert (n0 >= 0) |
|||
val (_(*pf*) | res) = fact (n0) |
|||
// |
|||
val ((*void*)) = println! ("fact(", n0, ") = ", res) |
|||
// |
|||
} (* end of [main0] *) |
|||
val () = assert (argc >= 2) |
|||
val n0 = g0string2int (argv[1]) |
|||
val n0 = g1ofg0 (n0) |
|||
val () = assert (n0 >= 0) |
|||
val (_(*pf*) | res) = fact (n0) |
|||
val ((*void*)) = println! ("fact(", n0, ") = ", res) |
|||
} |
|||
</syntaxhighlight> |
</syntaxhighlight> |
||
This can all be added to a single file and compiled as follows. |
This can all be added to a single file and compiled as follows. Compiling should work with various back end C compilers, e.g., [[GNU Compiler Collection]] (gcc). [[Garbage collection (computer science)|Garbage collection]] is not used unless explicitly stated with {{code|-D_ATS_GCATS}} )<ref>[http://www.ats-lang.org/TUTORIAL/contents/compilation.html Compilation - Garbage collection] {{webarchive |url=https://web.archive.org/web/20090804092735/http://www.ats-lang.org/TUTORIAL/contents/compilation.html |date=August 4, 2009}}</ref> |
||
< |
<syntaxhighlight lang="console"> |
||
$ patscc fact1.dats -o fact1 |
$ patscc fact1.dats -o fact1 |
||
$ ./fact1 4 |
$ ./fact1 4 |
||
</syntaxhighlight> |
|||
</source> |
|||
compiles and gives the expected result |
compiles and gives the expected result |
||
Line 154: | Line 165: | ||
=== Tuples and records === |
=== Tuples and records === |
||
* prefix @ or none means direct, ''flat'' or unboxed allocation |
|||
*:<syntaxhighlight lang="scala"> |
|||
val x : @(int, char) = @(15, 'c') // x.0 = 15 ; x.1 = 'c' |
|||
val @(a, b) = x // pattern matching binding, a= 15, b='c' |
|||
val x = @{first=15, second='c'} // x.first = 15 |
|||
val @{first=a, second=b} = x // a= 15, b='c' |
|||
val @{second=b, ...} = x // with omission, b='c' |
|||
</syntaxhighlight> |
|||
* prefix ' means indirect or boxed allocation |
|||
*:<syntaxhighlight lang="scala"> |
|||
'''val''' x : '(int, char) = '(15, 'c') ''// x.0 = 15 ; x.1 = 'c' '' |
|||
val x : '(int, char) = '(15, 'c') // x.0 = 15 ; x.1 = 'c' |
|||
val '(a, b) = x // a= 15, b='c' |
|||
val x = '{first=15, second='c'} // x.first = 15 |
|||
val '{first=a, second=b} = x // a= 15, b='c' |
|||
val '{second=b, ...} = x // b='c' |
|||
</syntaxhighlight> |
|||
; special |
|||
* special |
|||
With '|' as separator, some functions return wrapped the result value with an evaluation of predicates |
|||
*:With <code>|</code> as separator, some functions return wrapped the result value with an evaluation of predicates |
|||
'''val''' ( predicate_proofs | values) = myfunct params |
'''val''' ( predicate_proofs | values) = myfunct params |
||
Line 185: | Line 196: | ||
@(...) flat tuple or [[variadic function]] parameters tuple (see example's ''printf'') |
@(...) flat tuple or [[variadic function]] parameters tuple (see example's ''printf'') |
||
@[byte][BUFLEN] type of an array of BUFLEN values of type ''byte''<ref>[http://www.ats-lang.org/DOCUMENTATION/MISC/manual_main.pdf#page=65 type of an array] {{webarchive |url=https://web.archive.org/web/20110904160146/http://www.ats-lang.org/DOCUMENTATION/MISC/manual_main.pdf#page=65 |date=September 4, 2011 |
@[byte][BUFLEN] type of an array of BUFLEN values of type ''byte''<ref>[http://www.ats-lang.org/DOCUMENTATION/MISC/manual_main.pdf#page=65 type of an array] {{webarchive |url=https://web.archive.org/web/20110904160146/http://www.ats-lang.org/DOCUMENTATION/MISC/manual_main.pdf#page=65 |date=September 4, 2011}} types like @[T][I]</ref> |
||
@[byte][BUFLEN]() array instance |
@[byte][BUFLEN]() array instance |
||
@[byte][BUFLEN](0) array initialized to 0 |
@[byte][BUFLEN](0) array initialized to 0 |
||
=== Dictionary === |
=== Dictionary === |
||
{{Glossary begin}} |
|||
;sort:domain |
|||
{{term|sort:domain}} |
|||
<dd><syntaxhighlight lang="cpp"> |
|||
sortdef nat = {a: int | a >= 0 } // from prelude: ∀ ''a'' ∈ int ... |
sortdef nat = {a: int | a >= 0 } // from prelude: ∀ ''a'' ∈ int ... |
||
typedef String = [a:nat] string(a) // [..]: ∃ ''a'' ∈ nat ... |
typedef String = [a:nat] string(a) // [..]: ∃ ''a'' ∈ nat ... |
||
</syntaxhighlight></dd> |
|||
{{term|type (as sort)}}<dd>generic ''sort'' for elements with the length of a pointer word, to be used in type parameterized polymorphic functions. Also "boxed types"<ref name="introdep">{{Cite web |url=http://ats-lang.sourceforge.net/DOCUMENT/INT2PROGINATS/HTML/HTMLTOC/c2232.html |title=Introduction to Dependent types |access-date=2016-02-13 |archive-url=https://web.archive.org/web/20160312024014/http://ats-lang.sourceforge.net/DOCUMENT/INT2PROGINATS/HTML/HTMLTOC/c2232.html |archive-date=2016-03-12 |url-status=dead}}</ref> |
|||
<syntaxhighlight lang="scala"> |
|||
// {..}: ∀ a,b ∈ type ... |
// {..}: ∀ a,b ∈ type ... |
||
fun {a,b:type} swap_type_type (xy: @(a, b)): @(b, a) = (xy.1, xy.0) |
fun {a,b:type} swap_type_type (xy: @(a, b)): @(b, a) = (xy.1, xy.0) |
||
</syntaxhighlight> |
|||
</dd> |
|||
{{term|t@ype}}{{defn| linear version of previous ''type'' with abstracted length. Also unboxed types.<ref name="introdep"/>}} |
|||
{{term|viewtype}}{{defn| a domain class like ''type'' with a ''view'' (memory association)}} |
|||
;t@ype: linear version of previous ''type'' with abstracted length. Also unboxed types.<ref name="introdep"/> |
|||
{{term|viewt@ype}}{{defn| linear version of ''viewtype'' with abstracted length. It supersets ''viewtype''}} |
|||
;viewtype: a domain class like ''type'' with a ''view'' (memory association) |
|||
{{term|view}}<dd>relation of a Type and a memory location. The infix {{mono|@}} is its most common constructor |
|||
;viewt@ype: linear version of ''viewtype'' with abstracted length. It supersets ''viewtype'' |
|||
:{{code|T @ L}} asserts that there is a view of type T at location L |
|||
<syntaxhighlight lang="ocaml"> |
|||
;view: relation of a Type and a memory location. The infix @ is its most common constructor |
|||
:T @ L asserts that there is a view of type T at location L |
|||
fun {a:t@ype} ptr_get0 {l:addr} (pf: a @ l | p: ptr l): @(a @ l | a) |
fun {a:t@ype} ptr_get0 {l:addr} (pf: a @ l | p: ptr l): @(a @ l | a) |
||
fun {a:t@ype} ptr_set0 {l:addr} (pf: a? @ l | p: ptr l, x: a): @(a @ l | void) |
fun {a:t@ype} ptr_set0 {l:addr} (pf: a? @ l | p: ptr l, x: a): @(a @ l | void) |
||
</syntaxhighlight> |
|||
:the type of ptr_get0 (T) is ∀ l : addr . ( T @ l | ptr( l ) ) -> ( T @ l | T) // see manual, section 7.1. Safe Memory Access through Pointers<ref>[http://www.ats-lang.org/htdocs-old/DOCUMENT/MISC/manual_main.pdff#page=61 Manual, section 7.1. Safe Memory Access through Pointers]{{dead link|date=October 2016 |bot=InternetArchiveBot |fix-attempted=yes |
:the type of <code>ptr_get0 (T)</code> is <code>∀ l : addr . ( T @ l | ptr( l ) ) -> ( T @ l | T) // see manual, section 7.1. Safe Memory Access through Pointers</code><ref>[http://www.ats-lang.org/htdocs-old/DOCUMENT/MISC/manual_main.pdff#page=61 Manual, section 7.1. Safe Memory Access through Pointers]{{dead link|date=October 2016 |bot=InternetArchiveBot |fix-attempted=yes}} (outdated)</ref> |
||
<syntaxhighlight lang="ocaml"> |
|||
viewdef array_v (a:viewt@ype, n:int, l: addr) = @[a][n] @ l |
viewdef array_v (a:viewt@ype, n:int, l: addr) = @[a][n] @ l |
||
</syntaxhighlight> |
|||
</dd> |
|||
;T? :possibly uninitialized type |
|||
{{term|T?}}{{defn|possibly uninitialized type}} |
|||
{{Glossary end}} |
|||
=== pattern matching exhaustivity === |
=== pattern matching exhaustivity === |
||
Line 234: | Line 252: | ||
=== dataview === |
=== dataview === |
||
Dataviews are often declared to encode recursively defined relations on linear resources.<ref>[http://www.ats-lang.org/TUTORIAL/contents/dataviews.html Dataview construct] {{webarchive |url=https://web.archive.org/web/20100413053430/http://www.ats-lang.org/TUTORIAL/contents/dataviews.html |date=April 13, 2010 |
Dataviews are often declared to encode recursively defined relations on linear resources.<ref>[http://www.ats-lang.org/TUTORIAL/contents/dataviews.html Dataview construct] {{webarchive |url=https://web.archive.org/web/20100413053430/http://www.ats-lang.org/TUTORIAL/contents/dataviews.html |date=April 13, 2010}}</ref> |
||
<syntaxhighlight lang="ocaml"> |
|||
dataview array_v (a: viewt@ype+, int, addr) = |
|||
<nowiki> |
|||
| {l: addr} array_v_none (a, 0, l) |
|||
dataview array_v (a: viewt@ype+, int, addr) = |
|||
| { |
| {n: nat} {l: addr} |
||
array_v_some (a, n+1, l) |
|||
| {n: nat} {l: addr} |
|||
of (a @ l, array_v (a, n, l+sizeof a)) |
|||
</syntaxhighlight> |
|||
of (a @ l, array_v (a, n, l+sizeof a)) |
|||
</nowiki> |
|||
=== datatype / dataviewtype === |
=== datatype / dataviewtype === |
||
Datatypes<ref>[http://www.ats-lang.org/TUTORIAL/contents/datatypes.html Datatype construct] {{webarchive |url=https://web.archive.org/web/20100414020420/http://www.ats-lang.org/TUTORIAL/contents/datatypes.html |date=April 14, 2010 |
Datatypes<ref>[http://www.ats-lang.org/TUTORIAL/contents/datatypes.html Datatype construct] {{webarchive |url=https://web.archive.org/web/20100414020420/http://www.ats-lang.org/TUTORIAL/contents/datatypes.html |date=April 14, 2010}}</ref> |
||
datatype workday = Mon | Tue | Wed | Thu | Fri |
datatype workday = Mon | Tue | Wed | Thu | Fri |
||
Line 260: | Line 277: | ||
''on stack'' array allocation: |
''on stack'' array allocation: |
||
<syntaxhighlight lang="cpp"> |
|||
#define BUFLEN 10 |
#define BUFLEN 10 |
||
var !p_buf with pf_buf = @[byte][BUFLEN](0) // pf_buf = @[byte][BUFLEN](0) @ p_buf |
var !p_buf with pf_buf = @[byte][BUFLEN](0) // pf_buf = @[byte][BUFLEN](0) @ p_buf |
||
</syntaxhighlight><ref>[http://www.ats-lang.org/htdocs-old/DOCUMENT/MISC/manual_main.pdf#page=64 Manual - 7.3 Memory allocation on stack] {{webarchive |url=https://web.archive.org/web/20140809193400/http://www.ats-lang.org/htdocs-old/DOCUMENT/MISC/manual_main.pdf#page=64 |date=August 9, 2014}} (outdated)</ref> |
|||
See ''val'' and ''var'' declarations<ref>[http://www.ats-lang.org/htdocs-old/TUTORIAL/contents/val-and-var.html Val and Var declarations] {{webarchive |url=https://web.archive.org/web/20140809193101/http://www.ats-lang.org/htdocs-old/TUTORIAL/contents/val-and-var.html |date=August 9, 2014}} (outdated)</ref> |
|||
== References == |
== References == |
||
{{Reflist}} |
|||
<references/> |
|||
== External links == |
== External links == |
||
{{Wikibooks|ATS: Programming with Theorem-Proving}} |
{{Wikibooks|ATS: Programming with Theorem-Proving}} |
||
* |
* {{Official website|www.ats-lang.org}} |
||
* [http://www.ats-lang.org/Documents.html The ATS Programming Language] Documentation for ATS2 |
* [http://www.ats-lang.org/Documents.html The ATS Programming Language] {{Webarchive|url=https://web.archive.org/web/20141205101556/http://www.ats-lang.org/Documents.html |date=2014-12-05}} Documentation for ATS2 |
||
* [http://ats-lang.sourceforge.net/DOCUMENT/ The ATS Programming Language] Old documentation for ATS1 |
* [http://ats-lang.sourceforge.net/DOCUMENT/ The ATS Programming Language] Old documentation for ATS1 |
||
* [http://ats-lang.sourceforge.net/htdocs-old/DOCUMENT/MISC/manual_main.pdf Manual] Draft (outdated). Some examples refer to features or routines not present in the release (Anairiats-0.1.6) (e.g.: print overload for strbuf, and using its array examples gives errmsgs like "use of array subscription is not supported".) |
* [http://ats-lang.sourceforge.net/htdocs-old/DOCUMENT/MISC/manual_main.pdf Manual] Draft (outdated). Some examples refer to features or routines not present in the release (Anairiats-0.1.6) (e.g.: print overload for strbuf, and using its array examples gives errmsgs like "use of array subscription is not supported".) |
||
Line 277: | Line 297: | ||
* [http://bluishcoder.co.nz/tags/ats/ Learning examples and short use‑cases of ATS] |
* [http://bluishcoder.co.nz/tags/ats/ Learning examples and short use‑cases of ATS] |
||
{{ML programming}} |
|||
[[Category:High-level programming languages]] |
|||
[[Category:Multi-paradigm programming languages]] |
[[Category:Multi-paradigm programming languages]] |
||
[[Category:Declarative programming languages]] |
[[Category:Declarative programming languages]] |
||
[[Category:Functional languages]] |
[[Category:Functional languages]] |
||
[[Category:Object-oriented programming languages]] |
|||
[[Category:ML programming language family]] |
|||
[[Category:OCaml programming language family]] |
|||
[[Category:Statically typed programming languages]] |
|||
[[Category:Dependently typed languages]] |
[[Category:Dependently typed languages]] |
||
[[Category:Systems programming languages]] |
[[Category:Systems programming languages]] |
||
[[Category:Programming languages created in |
[[Category:Programming languages created in 2006]] |
||
[[Category:Cross-platform free software]] |
|||
[[Category:Free and open source compilers]] |
|||
[[Category:Extensible syntax programming languages]] |
|||
[[Category:Software using the GPL license]] |
|||
<!-- Hidden categories below --> |
|||
[[Category:Articles with example OCaml code]]<!-- Code example category family member nearest ATS. --> |
Latest revision as of 23:00, 30 October 2024
This article has multiple issues. Please help improve it or discuss these issues on the talk page. (Learn how and when to remove these messages)
|
Paradigms | multi-paradigm: functional, imperative, object-oriented, concurrent, modular |
---|---|
Family | ML: Caml: OCaml: Dependent ML |
Designed by | Hongwei Xi |
Developer | Boston University |
First appeared | 2006 |
Stable release | ATS2-0.4.2[1]
/ November 14, 2020 |
Typing discipline | static, dependent |
License | GPLv3 |
Filename extensions | .sats, .dats, .hats |
Website | www |
Influenced by | |
Dependent ML, ML, OCaml, C++ |
In computing, ATS (Applied Type System) is a multi-paradigm, general-purpose, high-level, functional programming language. It is a dialect of the programming language ML, designed by Hongwei Xi to unify computer programming with formal specification. ATS has support for combining theorem proving with practical programming through the use of advanced type systems.[2] A past version of The Computer Language Benchmarks Game has demonstrated that the performance of ATS is comparable to that of the languages C and C++.[3] By using theorem proving and strict type checking, the compiler can detect and prove that its implemented functions are not susceptible to bugs such as division by zero, memory leaks, buffer overflow, and other forms of memory corruption by verifying pointer arithmetic and reference counting before the program compiles. Also, by using the integrated theorem-proving system of ATS (ATS/LF), the programmer may make use of static constructs that are intertwined with the operative code to prove that a function conforms to its specification.
ATS consists of a static component and a dynamic component. The static component is used for handling types, whereas the dynamic component is used for programs. While ATS primarily relies on a call-by-value functional language at its core, it possesses the ability to accommodate diverse programming paradigms, such as functional, imperative, object-oriented, concurrent, and modular.
History
[edit]According to the author, ATS was inspired by Martin-Löf's constructive type theory, which was originally developed for the purpose of establishing a foundation for mathematics. Xi designed ATS “in an attempt to combine specification and implementation into a single programming language.”[4]
ATS is derived mostly from the languages ML and OCaml. An earlier language, Dependent ML, by the same author has been incorporated into ATS.
The first implementation, ATS/Proto (ATS0), was written in OCaml and was released in 2006. This was the pre-first edition of ATS and is no longer maintained. A year later, ATS/Geizella, the first implementation of ATS1, was released. This version was also written in OCaml and is no longer used actively.[5]
The second version of ATS1, ATS/Anairiats, released in 2008, was a major milestone in the development of the language, as the language was able to bootstrap itself. This version was written almost completely in ATS1. The current version, ATS/Postiats (ATS2) was released in 2013. Like its predecessor, this version is also almost entirely written in ATS1. The most recently released version is ATS2-0.4.2.[5]
Future
[edit]As of 2024[update], ATS is used mostly for research; less than 200 GitHub repositories contain code written in ATS. This is far less than other functional languages, such as OCaml and Standard ML, which have over 16,000 and 3,000 repositories, respectively. This is likely due to the steep learning associated with ATS, which is present because of the language's use of dependent type-checking and template instance resolution. These features usually require the use of explicit quantifiers, which demand further learning.[6]
As of 2024[update], ATS/Xanadu (ATS3) is being developed actively in ATS2, with the hope of reducing the learning needed by two main improvements:
- Adding an extra layer to ATS2 to support ML-like algebraic type-checking
- Type-based metaprogramming using algebraic types only[6]
With these improvements, Xi hopes for ATS to become much more accessible and easier to learn. The main goal of ATS3 is to transform ATS from a language mainly used for research, into one strong enough for large-scale industrial software development.[5]
Theorem proving
[edit]The main focus of ATS is to support formal verification via automated theorem proving, combined with practical programming.[2] Theorem proving can prove, for example, that an implemented function produces no memory leaks. It can also prevent other bugs that might otherwise be found only during testing. It incorporates a system similar to those of proof assistants which usually only aim to verify mathematical proofs—except ATS uses this ability to prove that the implementations of its functions operate correctly, and produce the expected output.
As a simple example, in a function using division, the programmer may prove that the divisor will never equal zero, preventing a division by zero error. Let's say, the divisor 'X' was computed as 5 times the length of list 'A'. One can prove, that in the case of a non-empty list, 'X' is non-zero, since 'X' is the product of two non-zero numbers (5 and the length of 'A'). A more practical example would be proving through reference counting that the retain count on an allocated block of memory is being counted correctly for each pointer. Then one can know, and quite literally prove, that the object will not be deallocated prematurely, and that memory leaks will not occur.
The benefit of the ATS system is that since all theorem proving occurs strictly within the compiler, it has no effect on the speed of the executable program. ATS code is often harder to compile than standard C code, but once it compiles, it is certain that it is running correctly to the degree specified by the proofs (assuming the compiler and runtime system are correct).
In ATS proofs are separate from implementation, so it is possible to implement a function without proving it, if desired.
Data representation
[edit]According to the author, ATS's efficiency[7] is largely due to the way that data is represented in the language and tail-call optimizations (which are generally important for the efficiency of functional languages). Data can be stored in a flat or unboxed representation rather than a boxed representation.
Theorem proving: An introductory case
[edit]Propositions
[edit]dataprop
expresses predicates as algebraic types.
Predicates in pseudo‑code somewhat similar to ATS source (see below for valid ATS source):
FACT(n, r) iff fact(n) = r MUL(n, m, prod) iff n * m = prod FACT(n, r) = FACT(0, 1) | FACT(n, r) iff FACT(n-1, r1) and MUL(n, r1, r) // for n > 0 // expresses fact(n) = r iff r = n * r1 and r1 = fact(n-1)
In ATS code:
dataprop FACT (int, int) =
| FACTbas (0, 1) // basic case: FACT(0, 1)
| {n:int | n > 0} {r,r1:int} // inductive case
FACTind (n, r) of (FACT (n-1, r1), MUL (n, r1, r))
where FACT (int, int) is a proof type
Example
[edit]Non tail-recursive factorial with proposition or "Theorem" proving through the construction dataprop.
The evaluation of fact1(n-1)
returns a pair (proof_n_minus_1 | result_of_n_minus_1)
which is used in the calculation of fact1(n)
. The proofs express the predicates of the proposition.
Part 1 (algorithm and propositions)
[edit] [FACT (n, r)] implies [fact (n) = r]
[MUL (n, m, prod)] implies [n * m = prod]
FACT (0, 1)
FACT (n, r) iff FACT (n-1, r1) and MUL (n, r1, r) forall n > 0
To remember:
{...} universal quantification [...] existential quantification (... | ...) (proof | value) @(...) flat tuple or variadic function parameters tuple .<...>. termination metric[8]
#include "share/atspre_staload.hats"
dataprop FACT (int, int) =
| FACTbas (0, 1) of () // basic case
| {n:nat}{r:int} // inductive case
FACTind (n+1, (n+1)*r) of (FACT (n, r))
(* note that int(x) , also int x, is the monovalued type of the int x value.
The function signature below says:
forall n:nat, exists r:int where fact( num: int(n)) returns (FACT (n, r) | int(r)) *)
fun fact{n:nat} .<n>. (n: int (n)) : [r:int] (FACT (n, r) | int(r)) =
(
ifcase
| n > 0 => ((FACTind(pf1) | n * r1)) where
{
val (pf1 | r1) = fact (n-1)
}
| _(*else*) => (FACTbas() | 1)
)
Part 2 (routines and test)
[edit]implement main0 (argc, argv) =
{
val () = if (argc != 2) then prerrln! ("Usage: ", argv[0], " <integer>")
val () = assert (argc >= 2)
val n0 = g0string2int (argv[1])
val n0 = g1ofg0 (n0)
val () = assert (n0 >= 0)
val (_(*pf*) | res) = fact (n0)
val ((*void*)) = println! ("fact(", n0, ") = ", res)
}
This can all be added to a single file and compiled as follows. Compiling should work with various back end C compilers, e.g., GNU Compiler Collection (gcc). Garbage collection is not used unless explicitly stated with -D_ATS_GCATS
)[9]
$ patscc fact1.dats -o fact1
$ ./fact1 4
compiles and gives the expected result
Features
[edit]Basic types
[edit]- bool (true, false)
- int (literals: 255, 0377, 0xFF), unary minus as ~ (as in ML)
- double
- char 'a'
- string "abc"
Tuples and records
[edit]- prefix @ or none means direct, flat or unboxed allocation
val x : @(int, char) = @(15, 'c') // x.0 = 15 ; x.1 = 'c' val @(a, b) = x // pattern matching binding, a= 15, b='c' val x = @{first=15, second='c'} // x.first = 15 val @{first=a, second=b} = x // a= 15, b='c' val @{second=b, ...} = x // with omission, b='c'
- prefix ' means indirect or boxed allocation
val x : '(int, char) = '(15, 'c') // x.0 = 15 ; x.1 = 'c' val '(a, b) = x // a= 15, b='c' val x = '{first=15, second='c'} // x.first = 15 val '{first=a, second=b} = x // a= 15, b='c' val '{second=b, ...} = x // b='c'
- special
- With
|
as separator, some functions return wrapped the result value with an evaluation of predicates
- With
val ( predicate_proofs | values) = myfunct params
Common
[edit]{...} universal quantification [...] existential quantification (...) parenthetical expression or tuple (... | ...) (proofs | values)
.<...>. termination metric @(...) flat tuple or variadic function parameters tuple (see example's printf) @[byte][BUFLEN] type of an array of BUFLEN values of type byte[10] @[byte][BUFLEN]() array instance @[byte][BUFLEN](0) array initialized to 0
Dictionary
[edit]- sort:domain
sortdef nat = {a: int | a >= 0 } // from prelude: ∀ ''a'' ∈ int ... typedef String = [a:nat] string(a) // [..]: ∃ ''a'' ∈ nat ...
- type (as sort)
- generic sort for elements with the length of a pointer word, to be used in type parameterized polymorphic functions. Also "boxed types"[11]
// {..}: ∀ a,b ∈ type ... fun {a,b:type} swap_type_type (xy: @(a, b)): @(b, a) = (xy.1, xy.0)
- t@ype
- linear version of previous type with abstracted length. Also unboxed types.[11]
- viewtype
- a domain class like type with a view (memory association)
- viewt@ype
- linear version of viewtype with abstracted length. It supersets viewtype
- view
- relation of a Type and a memory location. The infix @ is its most common constructor
T @ L
asserts that there is a view of type T at location L
fun {a:t@ype} ptr_get0 {l:addr} (pf: a @ l | p: ptr l): @(a @ l | a) fun {a:t@ype} ptr_set0 {l:addr} (pf: a? @ l | p: ptr l, x: a): @(a @ l | void)
- the type of
ptr_get0 (T)
is∀ l : addr . ( T @ l | ptr( l ) ) -> ( T @ l | T) // see manual, section 7.1. Safe Memory Access through Pointers
[12]
viewdef array_v (a:viewt@ype, n:int, l: addr) = @[a][n] @ l
- T?
- possibly uninitialized type
pattern matching exhaustivity
[edit]as in case+, val+, type+, viewtype+, ...
- with suffix '+' the compiler issues an error in case of non exhaustive alternatives
- without suffix the compiler issues a warning
- with '-' as suffix, avoids exhaustivity control
modules
[edit]staload "foo.sats" // foo.sats is loaded and then opened into the current namespace staload F = "foo.sats" // to use identifiers qualified as $F.bar dynload "foo.dats" // loaded dynamically at run-time
dataview
[edit]Dataviews are often declared to encode recursively defined relations on linear resources.[13]
dataview array_v (a: viewt@ype+, int, addr) =
| {l: addr} array_v_none (a, 0, l)
| {n: nat} {l: addr}
array_v_some (a, n+1, l)
of (a @ l, array_v (a, n, l+sizeof a))
datatype / dataviewtype
[edit]Datatypes[14]
datatype workday = Mon | Tue | Wed | Thu | Fri
lists
datatype list0 (a:t@ype) = list0_cons (a) of (a, list0 a) | list0_nil (a)
dataviewtype
[edit]A dataviewtype is similar to a datatype, but it is linear. With a dataviewtype, the programmer is allowed to explicitly free (or deallocate) in a safe manner the memory used for storing constructors associated with the dataviewtype.[15]
variables
[edit]local variables
var res: int with pf_res = 1 // introduces pf_res as an alias of view @ (res)
on stack array allocation:
#define BUFLEN 10
var !p_buf with pf_buf = @[byte][BUFLEN](0) // pf_buf = @[byte][BUFLEN](0) @ p_buf
See val and var declarations[17]
References
[edit]- ^ Xi, Hongwei (14 November 2020). "[ats-lang-users] ATS2-0.4.2 released". ats-lang-users. Retrieved 17 November 2020.
- ^ a b "Combining Programming with Theorem Proving" (PDF). Archived from the original (PDF) on 2014-11-29. Retrieved 2014-11-18.
- ^ ATS benchmarks | Computer Language Benchmarks Game (web archive)
- ^ "Introduction to Programming in ATS". ats-lang.github.io. Retrieved 2024-02-23.
- ^ a b c "ATS-PL-SYS". www.cs.bu.edu. Retrieved 2024-02-23.
- ^ a b Xi, Hongwei (2024-02-17). "githwxi/ATS-Xanadu". GitHub. Retrieved 2024-02-23.
- ^ Discussion about the language's efficiency (Language Shootout: ATS is the new top gunslinger. Beats C++.)
- ^ "Termination metrics". Archived from the original on 2016-10-18. Retrieved 2017-05-20.
- ^ Compilation - Garbage collection Archived August 4, 2009, at the Wayback Machine
- ^ type of an array Archived September 4, 2011, at the Wayback Machine types like @[T][I]
- ^ a b "Introduction to Dependent types". Archived from the original on 2016-03-12. Retrieved 2016-02-13.
- ^ Manual, section 7.1. Safe Memory Access through Pointers[permanent dead link ] (outdated)
- ^ Dataview construct Archived April 13, 2010, at the Wayback Machine
- ^ Datatype construct Archived April 14, 2010, at the Wayback Machine
- ^ Dataviewtype construct
- ^ Manual - 7.3 Memory allocation on stack Archived August 9, 2014, at the Wayback Machine (outdated)
- ^ Val and Var declarations Archived August 9, 2014, at the Wayback Machine (outdated)
External links
[edit]- Official website
- The ATS Programming Language Archived 2014-12-05 at the Wayback Machine Documentation for ATS2
- The ATS Programming Language Old documentation for ATS1
- Manual Draft (outdated). Some examples refer to features or routines not present in the release (Anairiats-0.1.6) (e.g.: print overload for strbuf, and using its array examples gives errmsgs like "use of array subscription is not supported".)
- ATS for ML programmers
- Learning examples and short use‑cases of ATS
- High-level programming languages
- Multi-paradigm programming languages
- Declarative programming languages
- Functional languages
- Object-oriented programming languages
- ML programming language family
- OCaml programming language family
- Statically typed programming languages
- Dependently typed languages
- Systems programming languages
- Programming languages created in 2006
- Cross-platform free software
- Free and open source compilers
- Extensible syntax programming languages
- Software using the GPL license