Jura Home | John Winn, December 2003 |
The main principle of Jura is that there is no difference between source code and data. Traditionally, programmers have kept the two very separate. Source code has been written and read by humans and the only program that reads it is the compiler. Data is written and read by programs and (if it is text data) by humans. The increasing use of XML shows the importance and flexibility of data that can be read and written by both humans and programs.
To allow source code to be read and written programmatically, we might consider using XML to represent our source code. The problem with XML is that it is too verbose to write programs in because it contains lots of redundant information (in the form of tag and attribute names) and does not support expressions. With a well-defined grammar, such redundant information can be inferred automatically and it can be removed if it is does not add to the readability of the program. Jura uses such an approach, whilst adding support for expressions, leading to a compact, generic language for representing structured data, including programs.
Let me illustrate this with an example.
Consider this simple Java class:
class Simple implements HasName,Cloneable { public void sayHello() { System.out.println("Hello World"); } }
This Java code is simple and readable. However, it is not a generic data language and cannot be used to define anything other than classes or interfaces. To fix this, we could instead choose to define classes in XML, in which case the above class would look something like this:
<class name="Simple"> <implements> <class id="HasName"> <class id="Cloneable"> </implements> <method name="sayHello" access="public" returns="void"> <method-call name="System.out.println"> <arg value="Hello World"/> </method-call> </method> </class>
It is hard to imagine a simpler class definition and yet this XML representation is verbose and unreadable. Furthermore, as XML does not allow for parsing/validation of expressions in attributes, expressions (such as the method call above) must be written as data structures. This is disastrous in terms of readability.
The Jura language removes the redundant information in XML and
allows for expressions, giving a generic language which is also
readable. The above class in the Jura language looks like this:
Class:Simple{ implements={HasName,Cloneable} Method:sayHello{ access=public // System.out.println("Hello World") } }
Jura can be used to represent any structured data, not
just classes. A Jura file can be created which corresponds to an
instance of any Jura class. This removes the need for the
equivalent of an XML schema as the schema for a Jura file is defined by
the class instance it represents. For example, a Jura source code
file which defines a class (such as the one above) is defining a
serialised instance of the jura.lang.element.Class
class. Other classes can be used to represent other structured
data. Validation of the Jura file (beyond simple syntax) is performed by
the same mechanisms as would validate the object if it were
constructed programmatically.
Here is an example of using the Jura language to represent some
structured data which is an instance of a Contact
class:
Contact{ name={first="John" last="Winn"} Telephone{type=MOBILE number="+44 1234 567890"} Address:home{ street="my street address" town="Cambridge" country="UK" } }
Jura allows such data files to be saved or loaded and validated at the language level. A Jura objectloader (corresponding to a Java classloader) is able to load and validate any structured data, not just classes.