Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "RoadmapOAW5"

(Redirecting to OAW)
 
(79 intermediate revisions by 11 users not shown)
Line 1: Line 1:
{| border=0
+
#REDIRECT [[OAW]]
| width=90% |
+
== Collection of features (rough) ==
+
 
+
In Version 5 we want to improve some of the Xtend language concepts and features.
+
Codename is Xtend++ :
+
 
+
=== Imports ===
+
The import mechanism should be overworked, so that every import is explicite.
+
We won't need any metamodel configuration in the workflow nor in the editors anymore.
+
This will not only make the setup simpler but will also improve the performance.
+
 
+
The syntax would change to something like the following:
+
 
+
import org:openarchitectureware:Extension; // native import
+
import EMF "my/package/model.ecore"; // non-native import
+
import UML "my/test.profile.uml" as profile; // non-native import with name space definition
+
import Java "my.test.Class"; // non-native import introduces java types and features form my.test.Class
+
import XSD "http://www.mywebsite.org/xsd/metamodel.xsd" // non-native import importing the types from an XSD file
+
... (think of Hibernate mapping files, Groovy, etc.)
+
 
+
==== Native import ====
+
A native import refers to another extension file imports all public members (types, functions, extensions).
+
 
+
==== Non-native Import ====
+
A non native import starts with an identifier pointing to an installed adapter.
+
The adapter is responsible for loading and converting the type information from the given string.
+
The syntax in the string is defined by the adapter.
+
 
+
==== Namespace definition ====
+
All members are included without namespace information. If you need a namespace you can explicitely define one per import.
+
 
+
==== Reexport ====
+
The reexport keyword will be supported.
+
 
+
=== Extensions/Functions ===
+
In the first version there will only be functions (aka. extensions).
+
Functions can be invoked either using the functional syntax or using the member syntax (operation like):
+
 
+
  myFunction(foo, bar) == foo.myFuntion(bar)
+
 
+
A function is declared as follows:
+
 
+
  (private|cached) ReturnType? functionName(declaredParameterList) guardExpression? : bodyExpression ;
+
 
+
Example:
+
  private doStuff(Entity this) name!=null :
+
      name+"Stuff";
+
 
+
or
+
 
+
  (private|cached) functionName(declaredParameterList) guardExpression blockExpression
+
 
+
Example:
+
  cached makeAbstract(Entity this) {
+
      abstract := true;
+
      name := 'Abstract'+name;
+
      return this;
+
  }
+
 
+
 
+
==== Polymorphic Guards ====
+
The guards are used for polymorhpic resolution of a called extension.
+
 
+
Example:
+
 
+
context Entity {
+
    String javaName() isAbstract : "Abstract"+name;
+
    String javaName() : name;
+
}
+
 
+
The dynamic semantics are:
+
 
+
* First select all possible features (functions and operations), based on the name and the types.
+
* Then order those features by parameter types (best match first).
+
* For each feature
+
* evaluate the guard
+
* if it doesn't evaluate to true skip it
+
* if it evaluates to true
+
* make sure that there is no second feature with the same signature where the guard evaluates to true
+
* if there is no such feature, we've found our feature -> success!
+
* else throw new Exception("Unambigous feature ... more than one feature ... bla")
+
 
+
* if there are features, but the guards evaluate to false, return null:
+
* if there is no feature, do "feature not found" (i.e. raising exception or invoking 'featureNotFound' operation)
+
 
+
The static semantics are straight forward: The guard must be of type boolean.
+
 
+
| valign=top |
+
{| border=0 cellspacing=3 cellpadding=4
+
! bgcolor="Gainsboro" | OAW Navigation   
+
|-
+
| bgcolor="GhostWhite" | [[OAW| Main Page]]
+
|}
+
|}
+
+
=== Object creation expression ===
+
We are thinking about a syntax to create model graphs inline.
+
We need this not only for model transformations but also for writing model transformation tests.
+
 
+
Example:
+
 
+
  new Entity {
+
      name := "Person";
+
      references += new Reference {
+
          name := "someRef"
+
          type := anotherEntity
+
      }
+
  }
+
 
+
==== Assignment Expressions ====
+
They are just another syntax for invoking a setter resp. adder-operation (which will be removed).
+
They return the assigned value.
+
 
+
==== create / cache semantics ====
+
The creation expression should replace the "create extension" mechanism from Xtend 1.0.
+
A creation of an Object is cached if the type name is suffixed with parenthesis containing any number of arguments.
+
The arguments act as a key.
+
 
+
Examples:
+
 
+
  var paramPerOperationAndName := new Parameter(op,name) {
+
      this.name := name;
+
      type := aDatatype;
+
  }
+
 
+
  var localSingleton := new Foo() {
+
      stuff := "bla";
+
  }
+
 
+
==== cross referencing ====
+
 
+
We need a way to specify cross references within a declared tree. The problem is that we need a reference to a created type after it has been created and before it will be initialized. This can be accomplished by adding a special assignment construct:
+
 
+
  var x := new localRef:=Entity {
+
      // x is not visible here, because the right hand expression has not been evaluated so far.
+
      // localRef holds a reference to the created but not yet initialized entity.
+
        name := "Person";
+
        references += new Reference {
+
            name := "partner"
+
            type := localRef
+
        }
+
      }
+
 
+
=== Code blocks ===
+
I (Sven) would like to discuss a ruby-like code block syntax.
+
A code block is similar to a chain expression ( a-> b-> x) with the additional features:
+
* provides variable declarations (Expression returning void)
+
* support early exit using the 'return' keyword, which forces outer code blocks to exit themselfes.
+
 
+
It's something like a pseudo imperative syntax.
+
 
+
Example:
+
 
+
  myExtension(String stuff) : {
+
    var x := stuff.length();
+
    if (x>56)
+
        return "Foo";
+
    else {
+
        return "Bar";
+
    }
+
  };
+
 
+
A code block is itself an expression consisting of a list of expressions.
+
It returns the value returned by the first executed "return-expression", or the value of the last expression.
+
 
+
We should make the colon and semicolon optional so that
+
myExt() { "stuff"; }
+
equals
+
myExt() : { "stuff"; };
+
 
+
=== if expression ===
+
As seen in the previous example, we want an if-expression. using if, else keywords.
+
 
+
if (predicate) expression (else if (predicate) expression)* (else expression)?
+
 
+
The else part is optional and will return null if not defined.
+
The following expression will return null:
+
  if (false) "Holla"
+
 
+
===Integration of Check===
+
The language check will be integrated into Xtend. That is you can define checks and extensions in the same file:
+
 
+
allEntities(emf::EObject obj) : eRootContainer.eAllContents.typeSelect(Entity);
+
+
context Entity {
+
    warning "name "+name+" should start with an uppercase letter" :
+
      name.firstToLowerCase()!=name
+
    error "duplicate name "+name :
+
      allEntities(this).select(e|e.name==name).size==1;
+
}
+
 
+
of course you can use everything we have defined before in checks, too. Example :
+
 
+
 
+
context Entity {
+
  error "duplicate name "+name {
+
      var entities := eRootContainer.eAllContents.typeSelect(Entity);
+
      allEntities(this).select(e|e.name==name).size==1;
+
  }
+
 
+
=== Definition of Types ===
+
So far we couldn't define Types within Xtend but had to define them using other techniques (ecore, Java, UML-profile, etc.).
+
Defining tyoes within Xtend would be a great feature. Because it is much simpler and faster to write them in text.
+
In addition we could define Type with logic (operations).
+
A syntax could look like this:
+
 
+
type Entity extends Named {
+
  // simple attributes
+
  String name;
+
  Boolean isAbstract {
+
      private set(aValue)
+
      get : name.startsWith("Abstract");
+
  };
+
 
+
  // references
+
  Set<Entity> superTypes;
+
  Set<Features>* features; // asterisk means containment
+
  Set<Reference>* references subsets features;
+
 
+
  // operations
+
  doStuff(String x) : x+name;
+
  doMoreStuff(String x) {
+
      name := x;
+
      features += var f := new Feature{
+
                      f.name:= x;
+
                      ...
+
                  };
+
  }
+
}
+
 
+
=== Template syntax ===
+
We want to come up with a simple template syntax integrated into Xtend.
+
Example:
+
  context Entity {
+
 
+
    toJava() :
+
    »package «packageName()»;
+
     
+
      public class «name» {
+
        «attributes.each(a|»
+
        public «a.type» «a.name»;
+
        «)»
+
      }«;
+
 
+
It's just a string literal with the xpand terminals '«' and '»'.
+
In addition if you use these type of string literals, string concatenation is implicit.
+
Under the hood we might come up with a special string type (for performance reasons), but it should be compatible to the oaw String type and therefore transparent to the user.
+
 
+
Files are opened thorugh extensions:
+
 
+
 
+
  generateCode(Entity e) :
+
    writeToFile(e.JavaFile(),e.toJava());
+
 
+
 
+
Something like this...
+
 
+
===Extensions overwrite semantics===
+
Extensions with the same signature will overwrite Operations.
+
Consider overwriting the toString() Operation  (which is invoked on String concatenations) for arbitrary meta types.
+
This will allow very readable templates.
+
 
+
 
+
===Optional parentheses for operations, functions, extensions without parameters===
+
We should discuss if we want to make empty parentheses on invocations of operations optional.
+
So that :
+
  my.operation()
+
equals
+
  my.operation
+
 
+
 
+
 
+
=== Closures ===
+
We'll have real closures, not the built-in stuff we have now.
+
 
+
Example:
+
 
+
  myList.select(e|e.name == "test")
+
 
+
or
+
  {
+
    String myText := "test";
+
    (Attribute)=>Boolean myClosure := e|e.name==myText;
+
    myList.select(myClosure);
+
  }
+
 
+
alternatively make use of type inference
+
 
+
  {
+
    var myText := "test";
+
    var myClosure := Attribute e|e.name==myText;
+
    myList.select(myClosure);
+
  }
+
 
+
declaration of select :
+
 
+
  List<T> select<T>(List<T> this, (T)=>Boolean closure) {
+
    ...
+
  }
+
 
+
=== Xpand Container ===
+
We'll have a possibility to add a string to a previously defined "outlet"
+

Latest revision as of 08:59, 9 December 2008

Redirect to:

Back to the top