Introduction to XMF

Contents

Superlanguages

What do the following implementations of the fibonnacci function have in common?
int fib(int x) {
return x <= 1 ? 1 : fib(x - 1) + fib(x - 2);
}

(define (fib x)
(if (<= 1)
x
(+ (fib (- x 1)) (fib (- x 2))))

function fib(int x) : int
begin
if x <= 1 then
begin
result := 1;
end
else
begin
result := fib(x - 1) + fib(x - 2);
end
end

define fib(x) {
x 1 <= [1] [x 1 - fib x 2 - fib +] if
}

The answer is that they are all written in the same language: XMF. XMF is an example of a new breed of language we call Superlanguages: languages that provide a superset of the syntax and semantics of other languages.

To top.

XMF in a nutshell

XMF is an open source extensible programming language designed for Language Oriented Programming. All aspects of XMF can be easily extended or redefined at run-time allowing the dynamic construction of domain specific languages (DSLs). XMF is also a mature full-featured stand alone language that has been used in industry for modeling and data intelligence applications.  This section gives an overview of just a few of the novel and interesting features of XMF.

Defining Domain Specific Languages (DSLs)

XMF can support the construction of whole new domain specific languages.  Here is an example of an interactive Quiz language defined in XMF:
@Model Quiz
// The Quiz model describes an interactive application
// for a TV quiz. Viewers are presented with a sequence
// of questions and get a final score...
score : Integer;
// Screen definitions

screen START()
vertical
text Welcome to the Quiz. Click the button to Start end
button Start
go Question1()
end
end
end

screen Question1()
vertical
text What is the capital of England? end
options Choice
option London;
option Paris;
option Madrid;
end

horizontal
button Next
// Next action continues...
end
button Quit
go Quit()
end
end
end
end

For a description of how the Quiz language was defined see here.

Extending existing languages

XMF supports the extension of XMF based languages.  For example here is a bit of a C-like language embedded in XMF's default language XCore.
if self.timeForC()
then
// Let's drop into C...
@C
// some C stuff....

int x;
x = 10;
while(x > 0) {
@x.println(); x = x - 1;
}

end
// Back out to XCore
else
self.noCforMe()
end
Moreover XMF languages can be arbitrarily interleaved, the following example contains XCore in the lexical scope of the C-like language:
if self.timeForC()
then
// Let's drop into C...
@C
// some C stuff....

int x;
x = 10;

// Back out to XCore

@For e in x
do
format(stdout,"~S~%",Seq{x})
end
end
// Back out to XCore
else
self.noCforMe()
end

For a description of how the C-like language is defined see here.

Meta-Object Protocol (MOP)

XMF implements a meta-object protocol (MOP) for language execution. This means that the rules of XMF language execution can be redefined for specific types of object. MOPs make languages very extensible whilst maintaining modularity and readability. For example here is the implementation of a MOP for a class of objects whose storage is maintained in a relational database:
  @Class DataBaseClass extends Class
    // This is a meta-class that implements a MOP
// for connecting to a database. The instances
// of a DataBaseClass are effectively rows in the
// table...

// Any database class has a reference to the external
// database table...

@Attribute table : DataBaseTable end

// The class knows about the primary key that is used
// to reference the individual objects in the table...

@Attribute primaryKey : String end
    @Operation getInstanceSlot(object:Object,name:String)

// This operation implements '.' for an instance of
// a database class. The object proxies the row in the
// table via the primary key value...

table.selectRow(object,primaryKey,name)
end
    @Operation new(Seq{key})

// When an instance of a database class is created
// this operation creates a new row...

table.createRow(self,key)
end
    // More MOP for the := operator etc...
  end

  // Create a database table...

@Class Personnel metaclass DataBaseClass end

// Set the table and primary key..

Personnel.table := DataBaseTable("jdbc:mysql://localhost/Personnel");
  // Creating an instance of the Personnel class will create a row...

  o := Personnel("Fred Brown");
  // Referencing a slot will use the getInstanceSlot operation...

  o.name
For more information about MOPs in XMF see here.

Integration with Java

XMF is strongly integrated with Java enabling any Java functionality to be accessed through XMF.
[1] XMF> Date := xmf.javaClass("java.util.Date");

<Root>

[1] XMF> Date();

Tue Dec 11 12:29:31 GMT 2007

[1] XMF>
XMF also allows Java classes and objects to be freely mixed with XMF data values. Java classes are referenced by name and can then be treated as ordinary XMF classes, and can even extend the Java classes with XMF operations and then freely mix the use of Java and XMF methods and operations. For example if a Java application implements a personnel record, this can be include in your XMF application and extend the Personnel class with some extra behaviour:
  @Class Personnel metaclass JavaClass

// This is an XMF class that 'wraps' behaviour around the
// Java class. Instances of this class can be created in
// XMF (in which case an instance of the Java class is
// created) or can be passed from a Java application...

JavaDescriptor("mypackage.Personnel")

@Operation reset()

// This is a new behaviour added to the Java class
// that is defined in terms of the methods provided by
// the Java class. When the Java methods are called, XMF
// deals with translating the XMF values to Java and
// vice versa...

self.setName("");
self.setAge(0);
self.setAddress("")
end
end
For more information about the Java integration functionality see here.

Pattern Matching

XMF supports pattern matching which allows values to be easily extracted from deep within structures without writing all the navigation code. This makes writing programs much less error prone, easier to read and therefore easier to maintain. For example we may want a program that processes a tree of integers and adds them all up:
  @Operation addUp(t:Tree):Integer
@Case t of
Branch(tree1,tree2) do
addUp(tree1) + addUp(tree2)
end
Leaf(n) do
n
end
end
end

First class undoability

XMF has a first class undo mechanism built into its VM.  With XMF state changes can be undone without needing to understand the precise state changes that have taken place, here is a program that exercises this feature:
let v = Vector(1)
in
format(stdout,"v before update : ~S~%",Seq{v});
@Undoable v.put(0,"Frank") end;
format(stdout,"v after update : ~S~%",Seq{v});
xmf.undoEngine().undo();
format(stdout,"v after undo : ~S~%",Seq{v});
xmf.undoEngine().redo();
format(stdout,"v after redo : ~S~%",Seq{v})
end;
This program gives rise to the following trace:
v before update : Vector{null}
v after update : Vector{Frank}
v after undo : Vector{null}
v after redo : Vector{Frank}
0:0:0:16 ms ]
true
[1] XMF>
More information about this feature can be found in the following forum entry (pending expansion into a documentation contribution).


To top.

Commercial Applications of XMF

XMF has been used to develop many commercial Data Intelligence applications including:


“XMF has provided BAE Systems with a powerful and flexible Model Driven Architecture (MDA) based solution, which has enabled us to successfully manage the configuration of complex aircraft software architectures, and the automatic generation of the build configuration blueprint for several aircraft platforms.”

BAE Systems

 "XMF has provided Artisan Software Tools with data import, export and translation solutions that enables Artisan Studio to communicate with other tools.  Ceteva's advanced data processing and transformation technology has been very effective. Their expertise and professionalism ensured that these solutions were delivered on time and efficiently."

Artisan Software Tools

To top.

XMF Documentation

XMF documentation is organized into three sections:


To top.