Showing posts with label builder API. Show all posts
Showing posts with label builder API. Show all posts

Monday, December 12, 2011

Writing Android UIs with Xtend

(Update: You can find the project on github : https://github.com/svenefftinge/xtend-android-experiments )

Xtend is a great fit for Android development. Since Xtend translates to Java source code, it's very easy to use it. After you've installed the Xtend SDK and the Android Development Tools you only need to do two things to get started.
  1. In Eclipse's preferences configure Xtend's compiler to generated to the gen/ folder.
  2. Add the Xtend lib and Google Guava to your project's classpath. 
Why is it useful?
Using a combination of Xtend's powerful extension methods and closures, it's possible to come up with a very declarative API to define UI models. It takes a couple of minutes to write an API which allows for defining a UI like the following:

class AppActivity extends Activity {
 
  override void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  
    contentView = this.linearLayout [
   
      orientation = VERTICAL
  
      view = this.textView ("Hello Android!")
  
      view = this.button ("Click Me!") [
        onClickListener = [ 
          this.textMessage('Hello you clicked me!').show
        ]
      ]
    ]
  } 
}

The API is made available by means of a static extension import. To outline the idea, here's how the button method is defined:

def static button(Context context, String text,
      (Button)=>void initializer) {
  val result = new Button(context)
  result.text = text
  initializer.apply(result)
  return result
}

Used as an extension method button can be invoked on any instance of Context. Since the last argument is a function type it can be passed after the actual method invocation:

view = this.button ("Click Me!") [
        onClickListener = [ 
          this.textMessage('Hello you clicked me!').show
        ]
      ]

Also note how you can simply assign a closure to onClickListener (which is btw. invoking setOnClickListener()). The compiler will automatically convert it to an abstract class of View.OnClickListener.
And everything is 100% statically typed!



Thursday, October 20, 2011

Xtend - Type-safe Groovy-style Builder API

In this post I want to focus on two cool language features which are both interesting for themselves but even more so in combination.

The Implicit Variable 'it'

If you name your variable 'it' all its members are accessible without qualifying them with the variable reference (just like 'this').

Example:

def appendFoo(StringBuilder it) {
  append('foo')
}

Also note that variables with the name 'it' are the only ones which can be overridden in lexical scopes. So you could for instance write the following, where the lambda expressions argument shadows the outer variable it.

def foo(List<String> it) {
  foreach[ it | toUpperCase ]
}

Sugar For Lambdas With One Argument

Many languages have special syntactic sugar for lambdas with just one argument. So does Xtend. The usual syntax for a closure with one argument is :

  [Type arg | expression-using-arg ]

But as lambdas with one argument are a common case, you can leave out the paramter declaration as in :

  [expression-using-it]

And of course the name of the single argument will be 'it'.

Closures As Last Arguments

We added another feature, which is common in many other popular languages: If you invoke a method where the last argument is a closure you can place the closure after the actual method invocation.

Example:

  newArrayList('a','b','c').foreach [ toUpperCase ]

Groovy-style Builder Syntax

Using these three language enhancements in combination allows for defining statically-typed groovy-style builder APIs. Check the screencast to see it in action.

Interesting? See xtend-lang.org for more cool features.