Upcoming Gosu Events

There are some Gosu-related events coming up that people might want to consider attending:

July 12, 2011 6-9PM – Sacramento Java Users Group

Exit Certified

I’ll be giving a brief talk on the experimental Protocols typeloader for Gosu and, time permitting, I’ll talk about Ronin, a small Gosu-based web framework.

July 18-20th – JVM Language Summit

Oracle Santa Clara Campus

Most of the Gosu Team will be at the JVMLS: Scott McKinney (Gosu Team Lead), Dumitru Petrusca (IDE Lead), David Green (XML Guru) and me. I’ll be giving a talk on the Protocols typeloader, and implementing language features as a library using The Open Type System.

July 25-29th – OSCON 2011

Oregon Convention Center, Portland, OR

I’ll be at OSCON this year, giving an introduction to Gosu And The Open Type System.

If you are going to be at any of these and want to meet up and talk Gosu, or just drink beer, let me know: email or twitter.


In Defense Of “Name : Type”

A big (really *the* big) syntactic departure that Gosu took from Java is around type declarations. In Java, you have the time-honored c-style of declaration: type, followed by name:

  public String aMethod(String aParameter) {
    String theString = "The String " + aParameter;
    return theString;
  }

In Gosu, you have the name first, followed by a colon, then the type:

  function aMethod(aParameter : String ) : String {
    var theString : String = "The String " + aParameter
    return theString
  }

(Note that you would typically omit the local variable’s type in Gosu and let type inference do its thing.)

This syntax comes down to us from Pascal and is the standard in ECMAScript, which is the language Scott originally based Gosu on.

Now, this is just syntax. Not really a big deal, right?

Turns out, in practice, this actually is kind of a big deal to people. Let me quote Stephen Colebourne:

@Carson, thanks for writing about Gosu. The feature literal element looks good, and fits my view of how such things should work with # for the meta level. Unfortunately, Gosu declares variables as name : type, which makes it rather unappealing to me. Fix that, and I might take a real look at the language…

Despite the fact that Gosu has everything that Stephen wants with respect to properties, he won’t take a real look at the language because of the syntax around types. So this obviously is a big deal to Stephen, and I can’t say I blame him: as Oscar Wilde said, only a very shallow person does not judge by appearances.

So, while admitting that it will look a little strange the first time to Java developers, let me try to give a small defense of the Gosu type syntax.

First off, I think that the Gosu syntax reads more naturally once you get used to it. Taking the example method above, reading it left to right in Java gives:

“Returning a String, the method ‘aMethod’ takes a String called ‘aParameter’”

In Gosu you have:

“The function ‘aMethod’ takes ‘aParameter’ of type String and returns a String”

I believe that most english speakers would find the latter a more natural way to explain the method. This is subjective of course, but, hey, we are talking about syntax here.

A less subjective advantage of Gosu’s syntax becomes apparent when you look at generic methods.

Consider this example:

   <T> T aGenericMethod(T aParameter) {
    return aParameter;
  }

Note that in Java the generic type variable must be declared first, off in space, so that it can precede the return type of the method, which could (but need not) contain a reference to the type variable.

In Gosu, this is expressed much more naturally:

   function aGenericMethod<T>(aParameter : T) : T {
    return aParameter
  }

Because the return type of the method comes at the end, the type variable can nestle comfortably after the name of the function. As a bonus, this is much closer to the syntax of generic classes, with the type variable following the name, rather than preceding it.

This has ramifications at the call site, as well. In Java, you must prefix the function call with a type if you want to give an explicit parameterization:

  anObject.<String>aGenericMethod( "Yay generics!" );

In Gosu, again, you use a more natural syntax:

  anObject.aGenericMethod<String>( "Yay generics!" )

Note how similar this is to the syntax used for class parameterization (e.g. ArrayList<String>).

As an interesting corner case, in Java you simply can’t invoke a parameterized generic method without a preceding expression:

  <String>aGenericMethod( "Yikes" );

will not compile, whereas this will:

  this.<String>aGenericMethod( "Hmmm" );

Gosu, on the other hand, has no such restriction, since the method parameterization comes comfortably after the method name:

  aGenericMethod<String>( "It just works" );

Now, these are admittedly fairly small advantages. But, nonetheless, they are advantages. I hope that outlining them will convince some of you who are skeptical about the “name : Type” syntax to look more deeply at Gosu: it is a very nice language with some interesting features. (Not the least, the Open Type System, which Scott wrote about here.)


Feature Literals + Enhancements + Blocks == Properties++

Stephen Colebourne recently commented on the lack of formal properties in Java:

  http://www.jroller.com/scolebourne/entry/beans_and_properties

I completely agree with Stephen that properties should have been introduced to Java long ago: they were one of the first things that Scott added to Gosu and they have been incredibly useful at Guidewire. They aren’t really sexy or novel, but they solve a lot of practical problems.

In the latest release of Gosu, we incorporated feature literals, which allow you to reference a property (or method) using the # operator, making properties even easier to work with. A commenter on Stephen’s blog mentioned Gosu’s feature literals and had some nice things to say about our implementation, but mentioned that they do not support a listener infrastructure, where you can register a listener with a property to be invoked when the property is written or read.

Gosu obviously can’t provide a general listener infrastructure: the Open Type System works with all sorts of different types, each with different property implementations, storage models and so on. *However*, using feature literals, blocks, generics and enhancements, you can add some pretty cool support for property listeners on types that can support them.

I’ve thrown together a quick example that shows how this can be accomplished.

The entirety of the code in this example is up on github here:

  https://github.com/carsongross/Properties-Callback-Example

First, let’s create a simple class that encapsules property storage and supports callbacks:

package props
uses java.util.HashMap
uses java.util.ArrayList

class PropHolder {
  var _props = new HashMap<String, Object>()
  var _callback = new HashMap<String, List<block(val:Object):Object>>()
                    .toAutoMap( \ s -> new ArrayList<block(val:Object):Object>() )
  
  function setProp( name : String, val : Object ) {
    for( cb in _callback[name] ) {
      val = cb( val )
    }
    _props[name] = val
  }
  
  function getProp( name : String ) : Object {
    return _props[name]
  }
  
  function addPropListener( name : String, blk : block(val:Object):Object ) {
    _callback[name].add( blk )
  }
}

This is some simple infrastructure that just wraps a hash map to store properties in, and maintains a list of listeners to execute when a property is invoked.

Next, let’s create a simple gosu class that uses this infrastructure to store a property:

package props

class ExampleGosuClass implements IHaveListenableProperties {
  var _props = new PropHolder() 
  
  property get Prop1() : String {
    return _props.getProp( "Prop1" ) as String
  }

  property set Prop1( s : String ) {
    _props.setProp( "Prop1", s )
  }
  
  override function addListener( propName : String, listener : block(Object):Object ) {
    _props.addPropListener( propName, listener )
  }
  
  property get ThisAsProp() : ExampleGosuClass {
    return this
  }
}

This class implements a simple interface, IHaveListenableProperties:

package props

interface IHaveListenableProperties {
  function addListener( propName : String, listener : block(Object):Object );
}

Finally, and this is where we get tricky, so follow along closely, we are going to enhance a specific parameterization of the return type of the expression foo#Bar, which is the API class gw.lang.reflect.features.BoundPropertyReference:

package props

uses gw.lang.reflect.features.BoundPropertyReference

enhancement BoundPropertyRefEnhancement : BoundPropertyReference<IHaveListenableProperties, Object>  
{
  function addListener( blk : block(obj:Object):Object ) {
    var root = this.Ctx as IHaveListenableProperties
    root.addListener( this.PropertyInfo.Name, blk )
  }
}

Note that this method will only appear on BoundPropertyReference‘s that have a IHaveListenableProperties object at their root, due to the particular parameterization that we have chosen to enhance. (Cool trick, eh?)

So, with all that infrastructure in place, we can now write this code:

uses props.*

var ex1 = new ExampleGosuClass()
var ex2 = new ExampleGosuClass()

ex1#Prop1.addListener( \ o -> { print( o ); return o + " Yay!" }  )
ex1.Prop1 = "Hello Listeners!" // prints "Hello Listeners!" 
print( ex1.Prop1 )             // prints "Hello Listeners! Yay!"

ex2.Prop1 = "Nope, no listener..."  // no listener, so no printing
print( ex2.Prop1 ) 

In this code, we create two instances of ExampleGosuClass and add a block-based listener to the Prop1 property on ex1. We then set the property on ex1, which invokes the block and prints out the original value, then transforms the value before storing it. Finally, we do the same with ex2 to demonstrate that the listener is bound only to the Prop1 property on ex1.

So we’ve used feature literals, enhancements and blocks to implement a slick little properties listening system in Gosu. A system like this could be integrated into, for example, an O/R framework or a web framework even more elegantly since the listener infrastructure could be entirely internal.

Just another example of the excellent tools in Gosu available for framework builders. I think you’ll see a lot of innovation in this space in the next year or so, as our tools mature and Gosu becomes more widely known.


The Open Type System vs. Code Gen

Cedric Beust took a look at Gosu’s Open Type System a few weeks back here:

  http://beust.com/weblog/2011/05/10/open-type-systems/

Overall it was a very fair, if brief, look at Gosu’s Open Type System. There was one point at the end, however, that I want to examine:

While elegant, Gosu’s open type system is basically just saving you from a code generation phase.

This is not entirely true, but it is hard to see why at first blush.

What *is* true is that most problems that are addressed with code generation in Java today can be more elegantly addressed in Gosu by using the Open Type System. And, due to the fundamental laziness of the Gosu compilation model, it is possible to model problems with much larger potential type spaces (so long as only a reasonable subset of that type space needs to be materialized at compilation time) since it is not necessary to generate all types up front. So, yes, the Open Type System is a sort of elegant code generation mechanism.

However, it is more than that.

To understand this, consider the Protocols type loader that I wrote a while back:

  http://protocols.github.com/

Protocols are an entirely foreign concept to Gosu. They are a way to achieve “static” duck typing: you define a Protocol in a .proto file, which looks an awful lot like an interface. However, unlike Java or Gosu interfaces, a value’s type does not need to implement a Protocol for the value to be assigned to a variable that has a Protocol type. Rather, the value’s type must conform to the Protocol: for every function defined in the Protocol, there must be an invocable function on the value’s type that can be invoked safely.

An example will help clarify.

Given this procotol:

package test

protocol Protocol1 {
  function doIt()
}

Any value with a static type that has a method doIt() can be assigned to it:

class Class1 {
  function doIt() { print( "In Class1" ) }
}

class Class2 {
  function doIt() { print( "In Class2" ) }
}

var p : test.Protocol1 = new Class1()
p.doIt() 

p = new Class2()
p.doIt()

// p = new ArrayList() -- Won't compile, since ArrayList doesn't have a doIt() method... 
//                        Unless you add one with an enhancement... :)

So, even though Class1 and Class2 are entirely unrelated, we are able to assign them both to a variable with a protocol type to which they both conform. We can’t assign an ArrayList to that variable, however, since an ArrayList does not have a doIt() function (although you could make ArrayList conform to the protocol by using an enhancement to add a doIt() method if you wanted to. But why would you do something crazy like that?)

I was able to implement Protocols in Gosu precisely because the Open Type System gave me more tools than simple code generation: I was actually able to implement the unique assignability semantics of my Protocol types using the IType#isAssignableFrom() method.

This is a level of control and power that mere code generation does not have.

Winning.


The Dynamic Code Evolution VM

Every single java developer out there needs to know about the Dynamic Code Evolution VM (DCEVM) being turned out by Thomas Würthinger and his team:

    http://ssw.jku.at/dcevm/

This is truly an amazing piece of technology. It enables full hot swap in a JVM, allowing you to change method signatures, add and delete methods and so on, with impunity. You will rarely need to restart your JVM once you start using it.

And it is available…. FOR FREE.

Guidewire has sponsored the development of the DCEVM ever since we first learned about it at the 2009 JVM Language Summit. It has been a huge productivity boon for us and is a crucial bit of technology in the Guidewire (and Gosu) stack.

More people need to know about the DCEVM.

Download it, stop bouncing your JVM, and tell a friend.


Gosu IntelliJ Plugin

In an effort to further IDE support for Gosu, we’ve just open sourced the IntelliJ plugin.

If you are interested, you can clone the repository here:

  https://github.com/gosu-lang/Gosu-IntelliJ-Plugin

Running the plugin involves:

  • Cloning the repository
  • Setting up the submodules (git submodule init then git submodule update)
  • Opening up the GosuPlugin.ipr project.

You’ll need to set up an IntelliJ SDK as well. Internally, we’ve been using the latest open source version. You can set this up as follows:

  • Check out from git://git.jetbrains.org/idea/community.git
  • build the editor using ant build
  • unzip the version for your platform in out/artifacts.

After you’ve done that, you can set up a new plugin SDK by pointing it at the directory in question.

Note that we will not be doing merges for the plugin in git, but if you’d like to submit a patch we can apply it internally and migrate it back out to the main repository.

Enjoy!


RE: Dear Java-Killers

Sven Efftinge has a blog post up giving his dos and don’ts for “java-killer” programming languages. I thought I’d go through his points one by one and see how Gosu stacks up.

1) Don’t make unimportant changes

I think Gosu does a pretty good job here: we didn’t set out to invent a whole new collections hierarchy and we have very few gratuitous or academic features. We tried to make it easy for Java developers to become productive in Gosu and keep on using the old familiar techniques and libraries they are used to.

2) Static Typing

Check.

3) Don’t touch generics

In Gosu we actually *simplified* Java generics (at the cost of correctness) by doing away with wildcards, which are the primary pain point for most Java developers. This is in contrast to other languages that have more complicated (but more correct) generics systems.

So I think Gosu improves on Java in a way that is easier for most Java developers to grok: just drop wildcards, and things usually work the way you want.

4) Use Type Inference

Check.

5) Care About Tool Support

Tentative Check. We currently have an Eclipse plugin and we expect to have extremely solid tool support in both Eclipse and IntelliJ by the end of the summer. This is our #1 priority right now.

6) Closures

Check. And we address Eric Parnell’s first comment with Enhancements, which allow us to add the usual functional suspects to java.util.Iterable (map(), where(), etc.)

7) Get Rid of Unused Concepts

Gosu retains bitshifts and a fall through switch statement. They come up every once in a while, and, since Java has them, it’s probably best to keep them around.

So Gosu stacks up well against Sven’s Dos and Don’ts.

Gosu isn’t an attempt to reinvent the way that we write code: it is an imperative language with some useful functional concepts as well. Most of the features and syntax are taken from various existing languages, and we’ve tried, for the most part, to deviate from Java as little as possible (e.g. feature literals use the familiar Javadoc syntax.)

The real innovation in Gosu is the Open Type System, which lets Gosu act as an excellent host language for other external DSL’s, such as XSD, WSDL or Java Properties Files, all of which can be accessed and manipulated in a statically typed manner from Gosu.

For Java developers, this should be pure win: all those resources you’ve had to work with using either code-gen tools or with an untyped dynamic API can now be used immediately: just drop your WSDL or Properties file on your classpath and, blam, go.

Sweet.


Follow

Get every new post delivered to your Inbox.

Join 39 other followers