Feature Literals
Posted: March 3, 2011 Filed under: Code Samples, Development, GScript 5 Comments »In the current open source release of Gosu there is a new feature called, er, feature literals. Feature literals provide a way to statically refer to the features of a given type in the Gosu type system. Consider the following Gosu class:
class Employee {
var _boss : Employee as Boss
var _name : String as Name
var _age : int as Age
function update( name : String, age : int ) {
_name = name
_age = age
}
}
Given this class, you can refer to its features using the '#' operator (inspired by the Javadoc @link syntax):
var nameProp = Employee#Name var ageProp = Employee#Age var updateFunc = Employee#update(String, int)
These variables are all various kinds of feature references. Using these feature references, you can get to the underlying Property or Method Info (Gosu’s equivalents to java.lang.reflect.Method), or use the feature references to directly invoke/get/set the features.
Let’s look at the using the nameProp above to update a property:
var anEmp = new Employee() { :Name = "Joe", :Age = 32 }
print( anEmp.Name ) // prints "Joe"
var nameProp = Employee#Name
nameProp.set( anEmp, "Ed" )
print( anEmp.Name ) // now prints "Ed"
You can also bind a feature literal to an instance, allowing you to say “Give me the property X for this particular instance“:
var anEmp = new Employee() { :Name = "Joe", :Age = 32 }
var namePropForAnEmp = anEmp#Name
namePropForAnEmp.set( "Ed" )
print( anEmp.Name ) // prints "Ed"
Note that we did not need to pass an instance into the set() method, because we bound the property reference to the anEmp variable.
You also can bind argument values in method references:
var anEmp = new Employee() { :Name = "Joe", :Age = 32 }
var updateFuncForAnEmp = anEmp#update( "Ed", 34 )
print( anEmp.Name ) // prints "Joe", we haven't invoked
// the function reference yet
updateFuncForAnEmp.invoke()
print( anEmp.Name ) // prints "Ed" now
This allows you to refer to a method invocation with a particular set of arguments. Note that the second line does not invoke the update function, it rather gives you a reference that you can use to evaluate the function with later.
Feature literals support chaining, so you could write this code:
var bossesNameRef = anEmp#Boss#Name
Which refers to the name of anEmp‘s boss.
You can convert method references to blocks quite easily:
var aBlock = anEmp#update( "Ed", 34 ).toBlock()
Finally, feature references are parameterized on both their root type and the features type, so it is easy to say “give me any property on type X” or “give me any function with the following signature”.
So, what is this language feature useful for? Here are a few examples:
- It can be used in mapping layers, where you are mapping between properties of two types
- It can be used for a data-binding layer
- It can be used to specify type-safe bean paths for a query layer
Basically, any place you need to refer to a property or method on a type and want it to be type safe, you can use feature literals.
Ronin, an open source web framework, is making heavy use of this feature. You can check it out here:
Enjoy!
That’s an innovation i wholeheartedly applaud, as the generous use in countless Java frameworks (JSF, JPA, Spring, …) of Strings to refer to Java properties and methods from Java annotations (i.e., from within Java code) has always scared me. I still find it incomprehensible that we’ve been able to do MyClass.class forever to get a Class literal, but the same idea hasn’t been generalised to get to the other java.lang.reflect types and the PropertyDescriptor. JDK7 won’t improve this either. So also in this respect Gosu shows the way!
As an aside, Scala also doesn’t have this feature, which, given its focus on resolving bugs at compile-time, is surprising. But then again it probably doesn’t particularly endorse a meta-programming style.
This feature is incredibly awesome. You can get all kinds of “dynamic” behavior this way while still maintaining type safety. The more I read about Gosu the more I like. I do wish the whole source code for the language was up a public repo somewhere, though… I won’t be able to use it on anything more than a hobby project until I can get the source and build it myself.
Ian,
Glad you like it.
We’re (still) working on getting the whole codebase out there. I expect we’ll have the implementation up on github by early summer. (It’s mainly a source control issue at this point, we don’t use git internally yet.)
Check out ronin if you’d like to play around with feature literals in a web framework:
http://ronin-web.org
Cheers,
Carson
[...] Posts Why Gosu?Feature LiteralsBurn-up and Burn-down [...]
[...] the latest release of Gosu, we incorporated feature literals, which allow you to reference a property (or method) using the # operator, which makes properties [...]