#REDIRECT [[Christophe de Dinechin]]
'''XL''' stands for eXtensible Language. It is a [[computer programming|computer]] [[programming language]] designed to support [[concept programming]].
{{R from merge}}
XL features programmer-reconfigurable syntax and semantics. Compiler ''plug-ins'' can be used to add new features to the language. A base set of plug-ins implements a relatively standard [[imperative programming|imperative language]]. Programmers can write their own plug-ins to implement application-specific notations, such as [[derivative|symbolic differentiation]], which can then be used similarly to built-in language features.
== Language ==
XL is defined at three different levels:
* XL0 defines how an input text is transformed into a [[parse tree]].
* XL1 defines a base language with features comparable to [[C_plus_plus|C++]]
* XL2 defines the standard library, which includes common data types and operators.
XL has no [[primitive types]] nor keywords. All useful operators and data types, like integers or addition, are defined in the standard library (XL2). XL1 is [[Porting|portable]] between different execution environments. There is no such guarantee for XL2: if a particular [[central processing unit|CPU]] does not implement floating-point multiplication, the corresponding operator definition may be missing from the standard library, and using a floating-point multiply may result in a [[compile-time]] error.
The [[Hello World]] program in XL looks like the following:
use XL.TEXT_IO
WriteLn "Hello World"
== Syntax ==
Syntax is defined at the XL0 level. The XL0 phase of the compiler can be configured using a syntax description file, where properties like the text representation and precedence of operators are defined. A basic syntax file defines common mathematical notations, like + for addition, with the usually accepted [[order of operations]].
The parse tree consists of 7 node types, 4 [[leaf node]] types (integer, real, text and symbol) and 3 [[internal node]] types (infix, prefix and block).
* ''integer'' nodes represent an integer [[literal]], such as <code>2</code>. The <code>#</code> sign can be used to specify a base other than 10, as in (<code>2#1001</code>). A separating underscore can be used to improve readability, as in <code>1_000_000</code>.
* ''real'' nodes represent non-integral numbers, such as <code>2.5</code>. Based-notations and separators can be used, as for integer nodes, for example <code>16#F.FFF#E-10</code> is a valid real literal.
* ''text'' nodes represent textual contents. They are normally surrounded by simple or double quotes, like <code>"Hello"</code> or <code>'a'</code>, but the syntax file can be used to add other separators, including for multi-line textual contents.
* ''symbol'' nodes represent names or operators. Names are sequence of alphanumeric characters beginning with a letter, like <code>Hello</code>. XL0 preserves case, but XL1 ignores case and underscores, so that <code>JohnDoe</code> and <code>john_doe</code> are the same name. Symbols are sequence of non-alphanumeric characters, like <code>*</code> or <code>=/=</code>.
* ''infix'' nodes represent two nodes related by an infix symbol, like <code>A+1</code> or <code>2 and 3</code>. Infix nodes are in particular used to separate lines, with an infix "new-line" symbol.
* ''prefix'' nodes represent two consecutive nodes, like <code>Write "Hello"</code>. It is also used for postfix notations, like <code>3!</code> or <code>Open?</code>.
* ''block'' nodes represent a node surrounded by grouping symbols, like <code>(A)</code>, <code>[Index]</code>. Indentation is internally represented by a block node.
With the default syntax file, the following is valid XL0, irrespective of any semantics.
A = B + "Hello"
It parses as:
infix("=",
symbol("A"),
infix("+",
symbol("B"), text("Hello")))
== Semantics ==
The XL1 phase is defined as a sequence of operations on the XL0 parse tree. These operations are provided by various compiler plug-ins, that are triggered based on the shape of the parse tree.
Special constructs, <code>translate</code> and <code>translation</code>, are provided by a plug-in designed to facilitate the writing of other plug-ins. The <code>quote</code> construct generates a parse tree. Here is how these notation can be used to implement a plug-in called <code>ZeroRemoval</code> that eliminates superfluous additions and multiplications by zero.
translation ZeroRemoval
when
'X' + 0
then
return X
when
'X' * 0
then
return quote(0)
A plug-in can be invoked on a whole file from the command line, or more locally in the source code using the ''pragma'' notation, as follows:
X := {Differentiate} d(sin(omega * T) * exp(-T/T0)) / dT
The XL1 phase contains a large set of plug-ins, notably <code>XLSemantics</code>, that provide common abstractions like [[subroutine]], [[data type]] and [[variable]] [[declaration]] and [[definition]], as well as basic [[structured programming]] statements, like conditionals or loops.
=== Type System ===
XL1 type checking is [[data type|static]], with [[generic programming]] capabilities that are beyond those of languages like C++ or Ada. Types like arrays or pointers, which are primitive in languages like C++, are declared in the library in XL. For instance, an one-dimensional array type could be defined as follows:
generic [DataItem : type; Size : integer] type array
A ''validated generic type'' is a generic type where a condition indicates how the type can be used. Such types need not have generic parameters. For instance, one can declare that a type is <code>ordered</code> if it has a less-than operator as follows:
// A type is ordered if it has a less-than relationship
generic type ordered if
A, B : ordered
Test : boolean := A < B
It is then possible to declare a function that is implicitly generic because the type <code>ordered</code> itself is generic.
// Generic function for the minimum of one item
function Min(X : ordered) return ordered is
return X
This also applies to generic types that have parameters, such as <code>array</code>. A function computing the sum of the elements in any array can be written as follows:
function Sum(A : array) return array.DataItem is
I : integer
for I in 0..array.Size loop
result += A[I]
=== Type-safe variable argument lists ===
Functions can be [[polymorphism|overloaded]]. A function can be declared to use a variable number of arguments by using <code>other</code> in the parameter list. In such a function, <code>other</code> can be used to pass the variable number of arguments to another subroutine:
// Generic function for the minimum of N item
function Min(X : ordered; other) return ordered is
result := Min(other)
if X < result then
result := X
When such a function is called, the compiler recursively instantiates functiions to match the parameter list:
// Examples of use of the Min just declared
X : real := Min(1.3, 2.56, 7.21)
Y : integer := Min(1, 3, 6, 7, 1, 2)
=== Operator overloading ===
Operators can be defined using the <code>written</code> form of function declarations. Below is the code that would declare the addition of integers:
function Add(X, Y: integer) return integer written X+Y
Such ''written forms'' can have more than two parameters. For instance, a matrix linear transform can be written as:
function Linear(A, B, C : matrix) return matrix written A+B*C
A written form can use constants, and such a form is more specialized than a form without constants. For example:
function Equal(A, B : matrix) return boolean written A=B
function IsNull(A : matrix) return boolean written A=0
function IsUnity(A : matrix) return boolean written A=1
== Development status and history ==
Historically, the XL compiler was written in C++. It had achieved a point where most of the features described above worked correctly, but writing plug-ins was a nightmare, because C++ itself is not extensible, so implementing <code>translate</code>-like statements was impossible. The parse tree was more complicated, with dozens of node types, because it was designed for cross-language support. Moka was a Java-to-Java extensible compiler using the same infrastructure.
Abdandoning the cross-language objectives and complex parse-tree structure, a complete rewrite of the compiler was started in 2003. The parse tree was vastly simplified down to the 7 XL0 nodes types now in use. This new compiler [[Bootstrap|bootstrapped]] in 2004, and all new development is now written in XL. However, this new compiler still has very incomplete XL1 support. Suport for generic types is notably deficient.
=== Ancestry ===
XL was inspired by a large number of other languages. In alphabetical order:
* [[Ada_language|Ada]] inspired some of large-scale program support, exception handling, tasking, and supportability aspects.
* [[Basic]], notably in the more modern variants that dispense of line numbers and support structured programming, showed how simple the syntax of a programming language could be. For instance, Basic remains one of the only modern languages to not mandate parentheses around subroutine calls.
* [[C_language|C]] was used as the standard to expect in terms of runtime and machine-level support. XL will not require a virtual machine to run.
* [[C_plus_plus|C++]] and the [[Standard template library]] demonstrated the need for good support of generic types, including implicit instantiation of generics (which Ada lacks).
* [[Fortran]]'s continued performance lead over C and C++ for numerical-intensive applications helped identify which language constructs would prevent useful optimizations.
* [[Java programming language|Java]] demonstrated the importance of a large, portable support library. Java containers also showed the limitations of an approach not based on generic programming. Interfacing with Java code remains an interesting challenge for XL.
* [[Lisp_programming_language|Lisp]] extensibility was considered as a key factor in its survival and relevance to this day. Lisp was the first language to normalize object-oriented features, despite having been designed years before object-oriented ideas were invented.
* [[Prolog]] demonstrated that alternative programming models are sometimes useful and highly productive. Every effort was made to ensure that a Prolog-style plug-in could be written for XL.
* [[Visual Basic]] showed how the parse tree representation can be dissociated from its visual presentation. Few people edit VB Forms textually. It is expected that XL edit-time plug-ins will one day provide similar capabilities, by directly manipulating the parse tree.
== External links ==
[http://xlr.sf.net The SourceForge development page]
|