Gosu thoughts - List and Array Expansion(*.)

Gosu is a language I have been working with since 2011. 2011 was not the first time I encountered Gosu. My first brief meeting with Gosu was back in 2007,  when I was on an insurance project in Wisconsin. At that time it was called GScript.

My first impression was that this is JavaScript mixed with Java. I obviously did not understand much about it since I was still new in my career. My impression today about Gosu is that it is Java with additional syntactic sugar as some would like to say.

The language has a little bit of JavaScript, (J)Ruby( or Groovy: groovy really is an attempt  of ruby on the JVM ) and C#. I think most java developers would be able to pick up Gosu quickly just as much as they would be able to pick up Groovy.

I cannot say that much for Scala. I think Scala is on a mission to hate everything about Java. Scala in my opinion is a one developer, one project tool and not for a project with multiple developers. I am not the only one who sees Scala in this way.

I still think Gosu has a long way from being accepted into the Java world. It needs to have all those tools Java developers are used too. It really needs an eclipse plugin. It will really gain acceptance if it could get integrated with Maven. I saw a feature I thought was interesting in Gosu and I thought I would blog about it. The feature is called List and Array Expansion(*.)

 

gosu lang

A quick example would be trying to iterate over an array of arrays or a collection of collections. Lets say you have an entity called Location. The Location entity has a list or array of another entity. We would call that entity Member. If we want to iterate over all the Members of a collection of Locations, the List and Array Expansion feature would be very handy.

In java you would do something like this:

 

List<Location> locations; // initialize with a valid collection of  Location objects

for(Location location : locations) {

for(Member member : location.getMembers()){

// do something with member

}

}

Something like that in Gosu would be written like

var locations :  List<Location> // initialize with valid collection of location objects

for( member in locations*.Members){

//do something with member

}

 

 

I know a lot of Java developers would find a feature like this very useful. I know I do. I was curious about how this feature really worked under the scene as far as the compilers goes and Alan Keefer and Carson Gross were extremely helpful with this thread .

 

There's some slightly-crazy stuff happening under the covers in the compiler, depending on if the right-hand side is a scalar or an array. If the right-hand side is a scalar, i.e. locations*.Name, then it'll act as a standard map() operation.  The compiled code will look more-or-less like if you called locations.map(\l -> l.Name).  If you call locations*.Buildings, it's like calling locations.flatMap(\l -> l.Buildings).  You can also technically use a method call on the right-hand size instead of a property, and if that method has a void return type, say locations*.doSomething(), it's like calling locations.each(\l -> l.doSomething()). The implementation in bytecode is a wee bit complicated, due to the number of different possibilities and some differences with regards to short-circuiting depending on if the right-hand side is a primitive value or not.  We also take a different path depending on if we can allocate the result array up front, which we can do if the left-hand size is an array or Collection and the right-hand side is a scalar (in which case we can cheaply know up front how big the result array should be) or if we have to compile the results into a temporary List which then gets turned into an array, which we do if the left-hand side is some other Iterable or if the right-hand side is an array or Collection, such that we don't know up-front how large to make the result array.  So there are a dozen or so different paths the compiler can ultimately take depending on all those factors.  But the end result is effectively like calling .map() or .flatMap() or .each(), depending on the right-hand-side of the expression. Personally, though, I'm not a huge fan of the operator, and prefer the explicitness of .map() and .flatMap() instead.  The *. operator predates the inclusion of blocks in Gosu, and I'm not sure we'd necessarily add it in these days if we didn't already have it, since we already have blocks for doing those sorts of mappings. -Alan

 

 

As you can see, Alan carefully explained the way Gosu handles this feature and what his preference was about the feature. There are many more interesting features you would find while using Gosu.

I think Gosu is approaching the use of the JVM in the right way. I think the idea of Java is dead is really a silly thing to say. 

Most developers just want to be able to make their daily task easier to perform and languages that embrace their previous knowledge would only help them achieve this goal.

It would also be easier for developers to integrate this new languages into their tool box. Some might say "why do you need another language?", I would say "why do need to watch a colored TV?"  Isn't the black and white TV doing exactly what it promised? Or why do you want to watch an HD TV? Isn't the colored TV doing what it promised? As humans, we evolve in various ways.

We take what we know and try to make it better.

There is 1 Comment

Add new comment