Showing posts with label language design. Show all posts
Showing posts with label language design. Show all posts

Friday, April 27, 2012

Xtend - New Language Features coming in M7

The team has been busy adding useful new features to Xtend (and all other languages built on top of Xtext's JVM-support). The upcoming M7 build (May 9) will come with the following enhancements:

"With"-Operator

A new operator '=>' has been added to the language and a corresponding extension method for java.lang.Object on the left hand side and a lambda expression on the right hand side. 
The with operator allows you to write:

new JTextField => [
  text = 'My Text'
]

Think of it as a let-expression, which allows for binding any object to the scope of the block, in order to do side-effects in it. Very handy when initializing objects.

Properties

A new annotation @Property will generate a Java-Bean-style getter and setter (if the field is not final) for an annotated field.

class Person {
  @Property String firstName
  @Property String lastName
}

The field itself will be renamed to _fieldname, to make one accesses the getter (resp. setter) when using the property syntax. OF course a getter or setter is only generated when not explicitly defined.

Data Classes (Value Objects)

Another annotation @Data, will turn an annotated class into a value object class. A class annotated with @Data has the following effect:
  1. all fields are flagged final, 
  2. getter methods will be generated (if not existent), 
  3. a constructor will be generated (if not existent),
  4. equals(Object) / hashCode() methods will be generated (if not existent),
  5. a toString() method will be generated (if not existent). 
Example:

@Data class Person {

  String firstName
  String lastName
}

For now the processing of the two annotations is hard coded into the compiler. However as described in this bugzilla, we want to add support for library level annotation processing. This will allow for adding other annotations like @Delegate etc. Also we want to make this very easy so you can easily define your own project-specific annotations. Unfortunately this will not make it into the upcoming release.

Multiple Classes in One File

You can now have any number of classes in a single file. Also the name of the first class must no longer match the file's name. But still if it matches it will be renamed in a rename refactoring.

Enhanced Field Declarations

Type inference for fields is now working, also the val and var keywords are available. 
Example:

class Person {
  @Property val firstName = 'Hans'
  @Property var lastName = 'Meier'
} 

Other areas we've been working on

Besides enhancing the language, we put a lot of effort into the IDE as well. Several new features like for instance a quick assist to add method declarations have been added. Also Sebastian is working on a rewrite of the type inference and linking engine, since the current implementation turned out to be a bit slow in certain situations.

Tuesday, November 01, 2011

Build Your Own JVM Language!

Xtext has already simplified development of domain-specific languages a lot. From a simple grammar definition you not only get a full language infrastructure but also powerful Eclipse-based tool support.
Now it's getting even better.

Today we release Xtext 2.1, which comes with surprisingly easy to use support for defining little languages targeting the JVM (Java Virtual Machine). You only need to define two files:
  • the grammar
  • a mapping to Java concepts
The first one is not new. It's still the same concise and readable grammar language we always had in Xtext.

The second script is the big deal: it allows you to map your language concepts to any number of Java types, fields and methods. By doing that you implicitly tell the framework what it needs to know to provide you with a fully working IDE including an incremental compiler!

We have written a nice little tutorial explaining the five steps needed to get a language like the following:

import java.util.List

package my.model {

    entity Person {
        name: String
        firstName: String
        friends: List<Person>
        address : Address

        op getFullName() : String {
            return firstName + " " + name;
        }
        
        op getFriendsSortedByFullName() : List<Person> {
            return friends.sortBy( f | f.fullName);
        }
    }
    
    entity Address {
        street: String
        zip: String
        city: String
    }
}

As you can see, it supports all kinds of advanced features such as Java generics and full expressions even including closures. But you not only get a working parser, linker and compiler but a fully-working high-end Eclipse plug-in on top! The screencast demos the resulting language and IDE and briefly shows how that can be built. Be creative and have fun!

Friday, April 15, 2011

Dear Java killers,

I love to see all the languages for the JVM popping up on almost a daily basis. Language design is big fun and it's the ultimate thing for a developer to write programs in a language you've built your own. :-)

I especially like the languages which try out new ideas and don't take themselves too seriously, because thinking out of the box is the best you can do in order to push things forward.

However there are also a couple of languages who try hard to attract a certain audience: The Java community. The number of Java developers out there is huge (it had been about 9 million two years ago) so if you could make only a part of this crowd love and use your language it would be a huge  success.
Languages like Groovy, Scala, Clojure, Gosu, Fantom, or lately (but not yet existent) Ceylon and Kotlin more or less try to attract this group. Actually I shouldn't really count Clojure in, because it is so different (I like it though). But all the other languages seem to try to be a better Java for Java developers.

Here are my seven most important Dos and Don'ts you should consider when developing a language for the Java community:

1) Don't make unimportant changes

People are reluctant to change. You should leverage existing knowledge where possible. Changing keywords because you think they sound better might be good for your ego but not for the acceptance of your language. Most languages fall into this trap somehow. The best example is the recently announced Ceylon, which renames all kinds of Java keywords with little reason. For instance the keywords extends and implements are different. In an interview on InfoQ Gavin King explains why he made that decision:
"Java is irregular here. In a class definition, the list of one or more interfaces follows the keyword "implements". In an interface the list of one or more interfaces follows the keyword "extends", which by coincidence may also appear in a class definition where it means something completely different (it is followed by a single class). Ceylon is regular. Lists of types always follow "satisfies". The keyword "extends" is always followed by an expression that instantiates the superclass."
Given that over nine million people are used to it and absolutely understand the semantics, I'd consider this an unfortunate decision.

2) Static Typing


The Java folks are used to top-notch tooling based on static type information. I don't think that errors found by static typing are actually that important, but the tooling you can build on top of this information is. And again it is a matter of the audience you are trying to attract. I wouldn't try to come up with a new statically-typed Ruby, since that doesn't make much sense. I know Mirah and it's not bad. My point is that the Ruby community is not interested in static typing.
Static typing is an important part of the Java culture and the problems it causes can be reduced (see my other advices). Besides that Groovy generally looks a bit overgrown, I'd say the lack of static typing has been a problem for the success of Groovy. Obviously the Groovy folks have understood that and try to fix it with Groovy++.

3) Don't touch generics

Static type systems are complicated. I don't think that more than 1% of all Java developers have really understood generics. All this co- and contra variance, wildcards, raw types, upper and lower bounds and the involved conversion rules are super complicated.
However If asked most Java developers think they know generics and feel quite comfortable with it.
I'm glad that languages like Scala do important work in this area by trying different approaches and having more sophisticated type systems. That's important for the industry but it scares off and there are nine million people out there who feel comfortable with an existing, quite sound type system (aside from very few practically irrelevant problems).

After all generics in Java are rather sound, it's just that the problem they solve is essentially complex.

Also note that reified generics are a bad idea. Type arguments are static type information. They are lying at runtime and the situations where they are helpful are rare. This also breaks interoperability with other JVM languages btw.

4) Use Type Inference

The biggest problem with static typing and generics is that people think that this is the reason why Java code is so cluttered with redundant type signatures. That's not true! It is just a language design decision that one has to be very explicit (or ceremonial) about everything he/she writes down.

A modern statically-typed language should make heavy use of type inference. That is in most situations you give the developer the choice whether to put a type signature or not. Code needs to be concise and readable.

Ceremonial languages like Java don't esteem their users, they think they are stupid and therefore force them to do all kinds of repetitive things. I'm glad the way language or library users are treated has changed in recent years such that developers are given more responsibility for what they do. Only then you can expect quality. The ceremonial style is the biggest problem with Java which urgently needs to be fixed.

5) Care about Tool Support (IDE)

Your language won't be successful within the Java community if it lacks decent tool support. Scala ignored this for quite some time and are now trying to catch up a bit.
My advice is to start working on the IDE while designing the language, because the IDE is an important part of the overall user experience people have with your language. Many syntactical decisions can have a great influence on how the tooling works. A simple example:

In Java when declaring a local variable, Eclipse first proposes you with a type and then afterwards with a name proposal using the simple name of the field's type :

Name proposals in Eclipse
This is simply not possible if you switch the order of type and name like in Scala ( name : Type ), because you first have to type the name.

This is just a simple example, there are other problems hiding in the complexity of a language implementation. Make sure you have an experienced IDE developer in your team and care about the holistic user experience of your language. For Java folks the IDE is an important part of it.

6) Closures

There is no way your language can be successful without closures. Besides the ceremonial verbosity and inflexible syntax of Java the lack of closures is where Java suffers most.
Also for closures type inference and a concise syntax are essential.

7) Get rid of old unused concepts


Removing unnecessary concepts is also a good idea. Java was designed for the C/C++ crowd and was meant to be used in embedded devices and the web. It turned out that it is used quite differently today and most Java developers really don't care about bit shifting, break and continue statements and fall-through switches anymore. Remove them!

APPENDIX

A personal note to the Gavin Kings in this world:

Eclipse Xtext is a language development framework, which not only helps implementing parsers, linkers, compilers and interpreters but also a top-notch Eclipse IDE. You should use it for any kind of language development, because it boosts your productivity and is fun to use.

A general note on Xtext:

Of course there is no mass-market for programming languages. Although Xtext handles them quite well and is used for commercial programming language IDEs, the main focus is to allow people to easily define small, focussed domain-specific languages. The good news is that we have developed a concise, statically typed Java like expression language library supporting everything I mentioned before. And *you* can easily embed it into your DSL! See what you can do with it: