Whiley is an experimental programming language that combines features from the
functional
Functional may refer to:
* Movements in architecture:
** Functionalism (architecture)
** Form follows function
* Functional group, combination of atoms within molecules
* Medical conditions without currently visible organic basis:
** Functional s ...
and
imperative paradigms, and supports
formal specification
In computer science, formal specifications are mathematically based techniques whose purpose are to help with the implementation of systems and software. They are used to describe a system, to analyze its behavior, and to aid in its design by veri ...
through function
preconditions
In computer programming, a precondition is a condition or predicate that must always be true just prior to the execution of some section of code or before an operation in a formal specification.
If a precondition is violated, the effect of th ...
,
postconditions In computer programming, a postcondition is a condition or predicate that must always be true just after the execution of some section of code or after an operation in a formal specification. Postconditions are sometimes tested using assertions w ...
and
loop invariant
In computer science, a loop invariant is a property of a program loop that is true before (and after) each iteration. It is a logical assertion, sometimes checked within the code by an assertion call. Knowing its invariant(s) is essential in ...
s.
The language uses
flow-sensitive typing
In programming language theory, flow-sensitive typing (also called flow typing or occurrence typing) is a type system where the type of an expression depends on its position in the control flow.
In statically typed languages, a type of an expres ...
also known as "flow typing."
The Whiley project began in 2009 in response to the "Verifying Compiler Grand Challenge" put forward by
Tony Hoare
Sir Charles Antony Richard Hoare (Tony Hoare or C. A. R. Hoare) (born 11 January 1934) is a British computer scientist who has made foundational contributions to programming languages, algorithms, operating systems, formal verification, and c ...
in 2003. The first public release of Whiley was in June, 2010.
Primarily developed by David Pearce, Whiley is an open source project with contributions from a small community. The system has been used for student research projects and in teaching undergraduate classes. It was supported between 2012 and 2014 by the Royal Society of New Zealand's Marsden Fund.
The Whiley compiler generates code for the
Java virtual machine
A Java virtual machine (JVM) is a virtual machine that enables a computer to run Java programs as well as programs written in other languages that are also compiled to Java bytecode. The JVM is detailed by a specification that formally describ ...
and can inter-operate with Java and other JVM based languages.
Overview
The goal of Whiley is to provide a realistic programming language where
verification
Verify or verification may refer to:
General
* Verification and validation, in engineering or quality management systems, is the act of reviewing, inspecting or testing, in order to establish and document that a product, service or system meets ...
is used routinely and without thought. The idea of such a tool has a long history, but was strongly promoted in the early 2000s through
Hoare's Verifying Compiler Grand Challenge. The purpose of this challenge was to spur new efforts to develop a ''verifying compiler'', roughly described as follows:
The primary purpose of such a tool is to improve
software quality
In the context of software engineering, software quality refers to two related but distinct notions:
* Software functional quality reflects how well it complies with or conforms to a given design, based on functional requirements or specification ...
by ensuring a program meets a
formal specification
In computer science, formal specifications are mathematically based techniques whose purpose are to help with the implementation of systems and software. They are used to describe a system, to analyze its behavior, and to aid in its design by veri ...
. Whiley follows many attempts to develop such tools, including notable efforts such as
SPARK/Ada,
ESC/Java
ESC/Java (and more recently ESC/Java2), the "Extended Static Checker for Java," is a programming tool that attempts to find common run-time errors in Java programs at compile time. The underlying approach used in ESC/Java is referred to as exten ...
, Spec#,
Dafny
Dafny is an imperative and functional compiled language that compiles to other programming languages, such as C#, Java, JavaScript, Go and Python. It supports formal specification through preconditions, postconditions, loop invariants, loop v ...
, Why3, and
Frama-C
Frama-C stands for ''Framework for Modular Analysis of C programs''. Frama-C is a set of interoperable program analyzers for C programs. Frama-C has been developed by the French Commissariat à l'Énergie Atomique et aux Énergies Alternatives ...
.
Most previous attempts to develop a verifying compiler focused on extending existing programming languages with constructs for writing specifications. For example,
ESC/Java
ESC/Java (and more recently ESC/Java2), the "Extended Static Checker for Java," is a programming tool that attempts to find common run-time errors in Java programs at compile time. The underlying approach used in ESC/Java is referred to as exten ...
and the
Java Modeling Language The Java Modeling Language (JML) is a specification language for Java programs, using Hoare style pre- and postconditions and invariants, that follows the design by contract paradigm. Specifications are written as Java annotation comments to the ...
add annotations for specifying preconditions and postconditions to
Java
Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's mo ...
. Likewise, Spec# and
Frama-C
Frama-C stands for ''Framework for Modular Analysis of C programs''. Frama-C is a set of interoperable program analyzers for C programs. Frama-C has been developed by the French Commissariat à l'Énergie Atomique et aux Énergies Alternatives ...
add similar constructs to the
C# and
C programming languages. However, these languages are known to contain numerous features which pose difficult or insurmountable problems for verification. In contrast, the Whiley language was designed from scratch in an effort to avoid common pitfalls and make verification more tractable.
Features
The syntax of Whiley follows the general appearance of imperative or object-oriented languages. Indentation syntax is chosen over the use of braces to delineate statement blocks, given a strong resemblance to
Python. However, the imperative look of Whiley is somewhat misleading as the language core is
functional
Functional may refer to:
* Movements in architecture:
** Functionalism (architecture)
** Form follows function
* Functional group, combination of atoms within molecules
* Medical conditions without currently visible organic basis:
** Functional s ...
and
pure.
Whiley distinguishes a
function
(which is
pure) from a
method
(which may have
side-effects
In medicine, a side effect is an effect, whether therapeutic or adverse, that is secondary to the one intended; although the term is predominantly employed to describe adverse effects, it can also apply to beneficial, but unintended, consequence ...
). This distinction is necessary as it allows functions to be used in specifications. A familiar set of primitive data types is available including
bool
,
int
, arrays (e.g.
int[]
) and records (e.g.
). However, unlike most programming languages the integer data type,
int
, is unbounded and does not correspond to a fixed-width representation such as 32-bit
two's complement
Two's complement is a mathematical operation to reversibly convert a positive binary number into a negative binary number with equivalent (but negative) value, using the binary digit with the greatest place value (the leftmost bit in big- endian ...
. Thus, an unconstrained integer in Whiley can take on any possible integer value, subject to the memory constraints of the host environment. This choice simplifies verification, as reasoning about modulo arithmetic is a known and hard problem. Compound objects (e.g. arrays or records) are not references to values on the heap as they are in languages such as
Java
Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's mo ...
or
C# but, instead, are
immutable
In object-oriented computer programming, object-oriented and Functional programming, functional programming, an immutable object (unchangeable object) is an object (computer science), object whose state cannot be modified after it is created.Goet ...
values.
Whiley takes an unusual approach to type checking referred to as "Flow Typing." Variables can have different static types at different points in a function or method. Flow typing is similar to ''occurrence typing'' as found in
Racket
Racket may refer to:
* Racket (crime), a systematised element of organized crime
** Protection racket, a scheme whereby a group provides protection to businesses or other groups through violence outside the sanction of the law
* Racket (sports equ ...
. To aid flow typing, Whiley supports
union
Union commonly refers to:
* Trade union, an organization of workers
* Union (set theory), in mathematics, a fundamental operation on sets
Union may also refer to:
Arts and entertainment
Music
* Union (band), an American rock group
** ''Un ...
,
intersection
In mathematics, the intersection of two or more objects is another object consisting of everything that is contained in all of the objects simultaneously. For example, in Euclidean geometry, when two lines in a plane are not parallel, thei ...
and negation types.
Union types are comparable to
sum types found in functional languages like
Haskell
Haskell () is a general-purpose, statically-typed, purely functional programming language with type inference and lazy evaluation. Designed for teaching, research and industrial applications, Haskell has pioneered a number of programming lan ...
but, in Whiley, they are not disjoint. Intersection and negation types are used in the context of flow typing to determine the type of a variable on the true and false branches of a runtime type test. For example, suppose a variable
x
of type
T
and a runtime type test
x is S
. On the true branch, the type of
x
becomes
T & S
whilst, on the false branch, it becomes
T & !S
.
Whiley uses a
structural
A structure is an arrangement and organization of interrelated elements in a material object or system, or the object or system so organized. Material structures include man-made objects such as buildings and machines and natural objects such as ...
rather than
nominal
Nominal may refer to:
Linguistics and grammar
* Nominal (linguistics), one of the parts of speech
* Nominal, the adjectival form of "noun", as in "nominal agreement" (= "noun agreement")
* Nominal sentence, a sentence without a finite verb
* Nou ...
type system.
Modula-3
Modula-3 is a programming language conceived as a successor to an upgraded version of Modula-2 known as Modula-2+. While it has been influential in research circles (influencing the designs of languages such as Java, C#, and Python) it has not ...
,
Go and
Ceylon
Sri Lanka (, ; si, ශ්රී ලංකා, Śrī Laṅkā, translit-std=ISO (); ta, இலங்கை, Ilaṅkai, translit-std=ISO ()), formerly known as Ceylon and officially the Democratic Socialist Republic of Sri Lanka, is an ...
are examples of other languages which support structural typing in some form.
Whiley supports ''reference lifetimes'' similar to those found in
Rust
Rust is an iron oxide, a usually reddish-brown oxide formed by the reaction of iron and oxygen in the catalytic presence of water or air moisture. Rust consists of hydrous iron(III) oxides (Fe2O3·nH2O) and iron(III) oxide-hydroxide (FeO(OH), ...
. Lifetimes can be given when allocating new objects to indicate when they can be safely deallocated. References to such objects must then include lifetime identifier to prevent
dangling references. Every method has an implicit lifetime referred to by
this
. A variable of type
&this:T
represents a reference to an object of type
T
which is deallocated with the enclosing method. Subtyping between lifetimes is determined by the ''outlives'' relation. Thus,
&l1:T
is a subtype of
&l2:T
if lifetime
l1
statically outlives lifetime
l2
. A lifetime whose scope encloses another is said to outlive it. Lifetimes in Whiley differ from Rust in that they do not currently include a concept of ''ownership''.
Whiley has no built-in support for concurrency and no formal memory model to determine how reading/writing to shared mutable state should be interpreted.
Example
The following example illustrates many of the interesting features in Whiley, including the use of postconditions, loop invariants, type invariants, union types and flow typing. The function is intended to return the first index of an integer
item
in an array of integer
items
. If no such index exists, then
null
is returned.
// Define the type of natural numbers
type nat is (int x) where x >= 0
public function indexOf(int[] items, int item) -> (int, null index)
// If int returned, element at this position matches item
ensures index is int > items[index] item
// If int returned, element at this position is first match
ensures index is int > no
// If null returned, no element in items matches item
ensures index is null > no :
//
nat i = 0
//
while i < , items,
// No element seen so far matches item
where no :
//
if items item:
return i
i = i + 1
//
return null
In the above, the function's declared return type is given the union type
int, null
which indicates that ''either'' an
int
value is returned or
null
is returned. The function's
postcondition In computer programming, a postcondition is a condition or predicate that must always be true just after the execution of some section of code or after an operation in a formal specification. Postconditions are sometimes tested using assertions wit ...
is made of three
ensures
clauses, each of which describe different properties that must hold of the returned
index
. Flow typing is employed in these clauses through the runtime type test operator,
is
. For example, in the first
ensures
clause, the variable
index
is retyped from
int, null
to just
int
on the right-hand side of the implication operator (i.e.
>
).
The above example also illustrates the use of an inductive
loop invariant
In computer science, a loop invariant is a property of a program loop that is true before (and after) each iteration. It is a logical assertion, sometimes checked within the code by an assertion call. Knowing its invariant(s) is essential in ...
. The loop invariant must be shown to hold on entry to the loop, for any given iteration of the loop and when the loop exits. In this case, the loop invariant states what is known about the elements of the
items
examined so far — namely, that none of them matches the given
item
. The loop invariant does not affect the meaning of the program and, in some sense, might be considered as unnecessary. However, the loop invariant is required to help the automated verifier using in the Whiley Compiler to prove this function meets its specification.
The above example also defines the type
nat
with an appropriate
type invariant. This type is used to declare variable
i
and indicate that it can never hold a negative value. In this case, the declaration prevents the need for an additional loop invariant of the form
where i >= 0
which would otherwise be necessary.
History
Whiley began in 2009 with the first public release,
v0.2.27
following in June 2010 and
v0.3.0
in September that year. The language has evolved slowly with numerous syntactical changes being made to-date. Versions prior
v0.3.33
supported first-class
string
and
char
data types, but these were removed in favour of representing strings as constrained
int[]
arrays. Likewise, versions prior to
v0.3.35
supported first-class set (e.g.
), dictionary (e.g.
) and resizeable list
[int]
), but these were dropped in favour of simple arrays (e.g.
int[]
). Perhaps most controversial was the removal of the
real
datatype in version
v0.3.38
. Many of these changes were motivated by a desire to simplify the language and make compiler development more manageable.
Another important milestone in the evolution of Whiley came in version
v0.3.40
with the inclusion of reference lifetimes, developed by Sebastian Schweizer as part of his
Master's Thesis
A thesis ( : theses), or dissertation (abbreviated diss.), is a document submitted in support of candidature for an academic degree or professional qualification presenting the author's research and findings.International Standard ISO 7144 ...
at the
University of Kaiserslautern
Technical University of Kaiserslautern (German: ''Technische Universität Kaiserslautern'', also known as TU Kaiserslautern or TUK) is a public research university in Kaiserslautern, Germany.
There are numerous institutes around the university, ...
.
References
{{Reflist
Academic programming languages
Experimental programming languages
High-level programming languages
Programming languages created in 2009
2009 software
Free software projects