Syntax Matters

add to Add to Blinkslist add to furl Digg it add to ma.gnolia Stumble It! add to simpy seed the vine TailRank post to facebook

(Note: I had been working on this post before this thread showed up on Artima today, so I figured it was an appropriate time to finish it off and publish it.)

One of Carson’s favorite phrases is to say that “syntax matters,” so I’m kind of stealing his idea here. But it’s something I firmly believe in as well, and it’s central enough to how we’ve designed GScript that it warrants a detailed explanation and defense.

The most common response to any sort of language criticism always seems to be, “But you can still do that in my language, here’s how.” But of course that response is pretty much always an option; any Turing-complete language has the same set of fundamental capabilities. The point is that it doesn’t just matter what your language can do; what matters is how you do things using the language. In the end it’s impossible to be truly objective and judgments will depend on individual taste, which is fine: I’m not trying to convince anyone that this or that way is better right now, but rather just that there are such things as better and worse ways to accomplish something and that the difference matters.

Of course, on the other hand you can take things too far; the overhead of learning new syntactic structures can be pretty high, so in my opinion it’s not worth jamming everything possible into the language in the name of greater expressivity. With that said, this entry will focus more on reasons why clean, expressive syntax is important, and the subject of how to keep things from going too far will be a different entry. I’m fairly certain that my analysis is incomplete here, but I’ve broken down my argument into 4 main reasons why the syntax of a language and how you express things matters.

Lines Of Code

All things being equal, less code is almost always better. In real life, of course, things are never really equal, but as a general rule I hope it’s non-controversial to say that being able to do task X with 50 lines of code is preferable to needing 500 lines of code to do task X. Less code takes longer to write, but the real benefits are around maintenance: less code means less of a chance of bugs, less to keep in your head, less for someone else (or yourself 6 months later) to read through and learn, less to test, and less to modify when you change the rest of the system.

There are always exceptions of course; 50 lines of incomprehensible code is probably not preferable to 200 lines of dead-simple, straight-line code, and 50 lines of highly-coupled code might not be preferable to 6 different buckets of 50 lines of independent, decoupled code. But from a language design perspective, reducing the amount of code a programmer needs to write is generally the right thing to do, and the fact that languages like Ruby and Python require so much less code than Java is one main reason why people generally end up being more productive in those languages.


I think it’s fair to say that code is often harder to read than it is to write, and it’s certainly true that code is read many more times than it’s written. As a result, writing readable code is critically important to any development project. Better syntax makes code more readable by more clearly expressing the intent of the author. For example, something like:

var userNames =\u -> u.Name)

is clearer to me than

List<String> userNames = new ArrayList<String>();
for (User user : users) {

It’s not just a lines-of-code issue, it’s the fact that in the first case you read the word “map” and it immediately conveys a large amount of information: that the developer wanted to extract a list of names, that the operation is non-destructive, etc. The second case requires slightly more work to understand because it looks like every other for loop in Java, so you have to dig more into the details to realize what it does (“okay . . . we’re iterating here to do a simple mapping, not to perform an operation on each element, partition the list up, transform the list in place”). Of course, you can write readable code in just about any language, and in the Java case you could always refactor it into a helper method, or use some functional-like library with an anonymous inner class. The point of better syntax is often that it makes it easier to write readable code; the fact that there’s only one obvious way to do most things in Python, for example, tends to make Python code much more readable than Perl code (at least in my opinion). You can write readable code in Perl, but you have to work at it; the language itself makes it difficult. Better syntax makes it easier to write readable code, which means that the code written in that language will, on average, be more readable.


One thing that I think people often don’t pay enough attention to is how easy it is to remember how to do things. The key metric is how often you have to use something in order to stop having to look it up or rely on an auto-complete treasure-hunt in the IDE. Are things so obvious that, even though you don’t exactly remember, your first guess is generally right? If so, the designer did a good job. Do you have to run off to the internet if you go more than 2 days without writing code using that syntax? That’s generally a bad sign.

Memorability plays into both reading and writing code; obviously it’s hard to read code if you don’t remember what the function calls mean or how the syntax elements interact, and it’s clearly laborious to write code if you have to constantly look in a reference guide.

Good syntax will cause things to stick better in your head, whereas less-clear syntax might make it nearly impossible to remember things. For example, XPath just refuses to stick in my brain; I don’t use it often enough, and while it’s powerful, the syntax is basically arbitrary as far as I can tell, which means that whenever I try to write XPath expressions or need to read someone else’s I have to look things up, slowing me down immensely. That’s the primary reason I didn’t add XPath support to GScript’s XML library; I’d much rather use closures with findFirst() or findAll() methods, since the intention is unambiguous and the extra code is more than made up for by the hours I don’t have to spend re-learning XPath every time I need to do something. Is it useful to have a consistent, declarative way to query XML trees? Sure, in cases where you don’t have a full-fledged programming language to use and something declarative and severely constrained is necessary. But otherwise it’s just too many arbitrary bits of information for me to remember on top of what I already have to keep in my head to program in Java/GScript, so I avoid it when I do have a real language to work with.

Note that this plays into both how much syntactic help you should add into a language and what syntax there should be. If you have too many special syntactic elements, it might become difficult to remember them all. If they’re arbitrary, inconsistent, or otherwise unfamiliar to people, it’ll definitely be difficult to remember them.


Related to the idea of memorability is the idea of discoverability: how easy is it to figure out how to do something when you’re first starting out? The easier the learning curve, the more likely you are to try to learn something new, and the less time you waste doing it. As with memorability, the ability to just guess and have that work out makes it easier to discover the correct path. In addition, well-designed syntax will often play well with auto-complete in editors, making it easier to explore using an IDE and learn an API that way. Lots more goes into that as well, such as proper encapsulation and object relationships, but syntax also helps.

The Upshot

Again, I’m not trying to convince anyone right now that my particular views on language design are right; the important thing to me is that people agree that syntax and language design matter, and that it’s the right debate to have in the first place. How you go about doing things in a language (or in interacting with an API) really does matter, and the details really are important.

The Cardinal Rule of Automated Testing

I’ve had numerous conversations over the past year or so with people who aren’t that familiar with writing automated tests (be they unit tests, functional tests, or what have you), and all the advice I give can really be summed up in one simple rule:

Your tests should break if and only if the product is broken

It seems pretty obvious on the face of it, which it is, but it also has some non-obvious implications.  I’ll start by breaking the statement out into its two halves, and then drill down on each to discuss its implications.

Your tests should break if the product is broken

On the surface of it, this is just a simple statement about test coverage:  you want to make sure that as much of your application as possible is covered by automated tests.  Full coverage of all combinations of behavior is, naturally, not possible, and there’s a tradeoff between the effort spent implementing and maintaining the tests and the number of bugs they prevent, so you naturally have to draw the line somewhere.  It’s important to know where you’re drawing the line, though, so this rule also implies that you need to have some sort of systematic description of what your application does that you can match up with your tests so you know what’s covered and what’s not.

The less obvious implication of this rule is that your tests should mimic, as closely as possible, the actual production environment and production paths through the code.  You can have what you think are the best unit tests in the world, but if all the units themselves are only tested in mocked-out, test-isolated bliss you might find that your tests don’t catch any actual product breaks.  There are more tradeoffs to be made here as well, this time between test development ease, execution speed, and maintenance burden and the realism of the tests.  But as a general rule, the closer you can get your automated tests to exercising your full stack in the same way it will be exercised in production, the more bugs your tests will catch.

Your tests should only break if the product is broken

This is, by far, the harder rule to abide by.  Test coverage is largely just a simple cost-benefit tradeoff:  more effort == more test coverage.  Reducing false positives in tests, however, is a much harder business.  We’ve been writing and debugging and maintaining huge stables of tests for years now, and I’d guess that 80% of our test breaks are still false positives in the sense that they indicate that the test needs to be fixed rather than that the underlying code needs fixing.  All that test fixing takes an enormous amount of time.  We pay the price because it’s worth it, but we’re always trying to find ways to reduce it.

One way to reduce it is via the aforementioned strategy of making the tests mimic the production environment (as we’ve done with our TestBase infrastructure).  That also prevents false positives by ensuring that tests don’t break simply because the test code path has diverged from the production code path, for example by having a mock no longer properly implement the semantics of thing being mocked out, or having a test set up data that’s not valid.

A related technique is testing at the highest level of abstraction possible.  This technique tends to prevent false positives that come because of implementation changes that don’t actually affect behavior; basically, if you unit test at too fine a level you end up pinning yourself to a certain implementation, and changing that implementation can cause a massive test maintenance headache even if the change is correct and behavior-neutral.  For example, I wrote the XSD typeloader for the Bedrock series of releases, which involved a ton of helper classes for handling all the different XSD features.  Those classes all have some unit tests, but I put much more effort into testing things from the GScript level on down, which is really the level at which the semantics of the type system are meaningful; everything else is just an implementation detail.  As I changed the implementation around (which I did often), those tests would still be valid since they described invariants about how the system should function regardless of the implementation, whereas I’d simply throw out the unit level tests that became invalid.  Since I had the higher-level tests, I wasn’t as worried that I’d lose coverage by throwing out those unit-level tests.

One of the more difficult problems in avoiding false positives is around web UI testing:  you generally either have to pin your tests to the text on the page, which is naturally pretty fickle, or you have to pin your tests to generated HTML ids, which are also often fairly unstable.  Our old, pre-Bedrock UI testing framework had this problem:  every time someone renamed a link or changed a button, some large number of tests would break with incomprehensible error messages that were difficult to track down (i.e. is the button “foo” not on the page because it’s been renamed, removed, or because the page is just broken?).  We’ve solved a lot of those problems with our new framework (not yet fully baked for customer use at this point, I believe) that exposes a strongly-typed object model for writing tests against the pages, which means that renaming or removing a button will cause related tests to break at compilation time, making it infinitely easier to fix them proactively.

Lastly, good coding practices will generally help you out with reducing false positives, or at least making them easier to identify and fix.  Treat your test code like it’s real, production code and pay attention to decomposition, code reuse, variable and method naming, etc.  It might not strictly result in fewer false positives, but it will make them easier to fix if the fix only needs to be made in one well-named method instead of in dozens of copy-and-pasted methods littered all over the code base.

These might all seem like obvious rules, but sometimes we overlook the most obvious things, so it never hurts to go back to first principles and ask basic questions like “Will this test break if the product is broken?” or ”
How do I make this test robust in the face of potential implementation changes?”

GScript > Java (pt. 4)

A few weeks ago when I was writing some java code in the GScript runtime, I came across a situation where I needed to get all the ParseWarnings on a parsed element with a given resource tag, which is the unique identifier for the type of error. Turns out I had already written the code to get all the ParseErrors that had a given resource code. It looked like this:

  public List<ParseError> getParseErrorsOfType(  ResourceKey key ) {
    ArrayList<ParseError> lst = new ArrayList<ParseError>();
    for( ParseError pe : getParseErrors() ) {
      if( pe.getResouceKey() == key ) {
        lst.add( pe );
    return lst;

Now, I could have just duplicated that method and replaced Error with Warning and everything would have been fine. But that’s a bit offensive because getResourceKey() is a method on ParseIssue, which is the base class of ParseError and ParseWarning, and it just seems wrong to duplicate that much code. So I stared at it a bit and then realized (with Keefs help) that I was going to have to put my generics hat on and write a generic method:

  public <T extends ParseIssue> 
         List<T> getParseIssuesOfType(  ResourceKey key, List<T> src ) {
    ArrayList<T> lst = new ArrayList<T>();
    for( T pi : src ) {
      if( pi.getResouceKey() == key ) {
        lst.add( pi );
    return lst;

And I could then write these methods:

  public List<ParseError> getParseErrorsOfType(  ResourceKey key ) {
    return getParseIssuesOfType( key, getParseErrors() );

  public List<ParseWarning> getParseWarningsOfType(  ResourceKey key ) {
    return getParseIssuesOfType( key, getParseWarnings() );

Well, going through all that had a certain intellectual frisson, I’ll admit, as I pieced together exactly what arguments I had to pass in and how to declare the generic method correctly. Loads of fun. But it took me about two minutes to get it all just right. Now, I don’t consider myself the sharpest tool in the shed but I’m not a total idiot and I think I’ve got a better than average handle on generics. Despite this, I had to stop for a couple of minutes, put on my aforementioned generics hat, bust out my slide-rule and write that incomprehensible code. In pure clock time it would have been a lot faster to just duplicate the method, feel bad about it for a second, and then move on.

Soooooo, let’s look how I would have implemented that method if I were lucky enough to be writing it in GScript:

  function getParseErrorsOfType(  key : ResourceKey ) : List<ParseError> {
    return ParseErrors.findAll( \ pe -> pe.ResourceKey == key )

Now, that’s a method that I feel a lot less bad about duplicating. Good old ctrl-d and a quick edit gives:

  function getParseWarningsOfType(  key : ResourceKey ) : List<ParseWarning> {
    return ParseWarnings.findAll( \ pw -> pw.ResourceKey == key )

That would take me about ten seconds and I’d move on with nary a thought, and the amount of code duplication is nearly as negligible as the java solution above.

And that’s something profound.

The type-inference and closures that GScript offers allow you to pack a lot more meaning into a single line, helping you avoid writing helper methods and classes, all of which bog your code down with unnecessary weight. The type-inference, in particular, dramatically reduces the burdens of generics, allowing you to skate along the surface of your algorithms without delving too deeply into the type details. Things just work themselves out.

So, in short, GScript makes the easy solution also the right solution.


Language Comparison – Properties

It’s generally accepted wisdom by now that giving client objects direct access to data stored on a class is a bad idea; it violates encapsulation, prevents you from changing implementations in interface-neutral ways, and prevents you from doing other things like lazy-computation or evaluation that might eventually prove necessary for the sake of correctness or performance. In addition, it’s often useful to have operations that look like simple field gets and sets but that actually do additional logic and aren’t tied to any particular data value.

Most modern languages, then, have adopted conventions and/or techniques around using methods to expose private data. In Java, for example, the standard approach is to make all instance variables private and to use get/set/is methods to access and manipulate the data instead. It’s a very useful convention, but it’s such a fundamental pattern that other languages have gone even further by making it possible to expose methods that look like variable accesses, allowing for variable-like accesses and assignments. The names aren’t the same across all languages, but I’ll use the term “property” to refer to get/set methods that are exposed as simple variable accesses, since that seems to be the most common term. So let’s look at how you go about defining and using properties in each language. The use case, for illustration purposes, will be a User object that has a Name property.


Java doesn’t have built-in support for properties, so you have to define the getters/setters yourself:

private String _name;
public String getName() { return _name; }
public void setName(String name) { _name = name; }

Similarly, to access the property you have to call the method:

System.out.println("Hello, my name is " + user.getName());

The Java introspector, used for JavaBeans, will combine the getName() and setName() methods into a single Name property that is both readable and writable, so for the sake of reflective access using BeanInfo there is some concept of a property. Not at the source code level, though.


GScript has a first-class notion of properties, allowing you to declare things like so:

var _name : String
property get Name() : String { return _name }
property set Name(name : String) { _name = name }

Since defining a property to wrap a private variable is such a common pattern, there’s also a shorthand notation for that:

var _name : String as Name

Which is equivalent to the above declarations. You can also start by using the “as” syntax and then explicitly define the property getter or setter if you like. Using the properties is what you’d expect:

user.Name = "Bob"
print("Hello, my name is " + user.Name)

There are a couple of other things worth noting here. First of all, GScript follows the JavaBeans naming convention that properties start with a capital letter, which helps make clear that they’re properties and not instance variables. Secondly, GScript exposes Java classes the same way the Java introspector does, so a Java class with getName() and setName() methods will, from GScript, appear to have a Name property instead of getName() and setName() methods.


All instance variables in Ruby are private, and the only way to expose them is via a method. Ruby makes parentheses optional on method calls, allows white space in all sorts of places, and allows all sorts of interesting characters to be used in method names, so ‘=’ is actually a valid character in a method definition. So you could do things in a brute-force manner like:

def name

def name=(val)
  @name = val

Note that in the second case, the = character is part of the method name; including = in a method name makes it possible for it to appear on the left-hand side of an assignment statement. I don’t actually know Ruby well enough to say if that’s built in to the parser or just a result of the fact that parentheses are optional and whitespace is permitted in interesting places.

Since this is such a common pattern, Ruby has built-in methods for creating what Ruby calls “attributes,” their name for the property concept. The methods are just like any other Ruby method and use metaprogramming to dynamically create the getter/setter methods. So the above code could be simplified down to:


Note that this makes use of Ruby’s concept of symbols (that’s what :name is; the ‘:’ character at the start denotes this as a symbol), which are used all over the place for metaprogramming in Ruby.

Accessing the attributes in Ruby looks like what you’d expect: = "Bob"
puts "Hello, my name is ${}"


Python’s notion of properties is a bit more complicated; in fact, despite reading through all the chapters on object-orientation in Dive Into Python I didn’t know it existed until I read through the Django Database API documentation and clicked through to see how they managed to make their foreign-key references work.

It turns out that Python’s support for properties is via a general-purpose mechanism called Descriptors. Descriptors are used for much more than just properties, but in the context of properties they’re a bit hard to understand since they turn things kind of on their head. A descriptor is an object that has special methods that define what to do when the object is treated like a variable and is accessed, set, or deleted (since that’s possible in Python). So instead of defining getName/setName methods on the User class, in Python what you do is create a descriptor object that’s bound to the class-level “name” variable, and then when that class-level variable is accessed or assigned to the methods on the “name” descriptor object will be invoked. Don’t feel bad if your response to that is “Huh?”

There’s a built-in method called “property” in Python that lets you create a descriptor given the function parameters, so to define the “name” property on the User class in Python you would do:

def get_name(self): return self.__name
def set_name(self, value): self.__name = value
name = property(get_name, set_name)

So what this means is that name is an object, and that object will call back to the get_name on User when it is accessed and to set_name when it’s assigned to. It gets the job done, but not as elegantly as in Ruby or GScript in my opinion; it feels like the bolts are showing a little bit.

The use of the property, though, looks like what you’d expect: = "Bob"
print "Hello my name is %s" %

Language Comparison – List Mapping

Continuing with the language comparison theme, I’ll look at another common list processing operation: mapping a list to another list. Say I’ve got a list of user objects and I want to turn that into a list of user names instead. Here’s how it looks in each of the languages.


Using the standard for-each approach:

List<String> userNames = new ArrayList<String>();
for (User user : users) {

Or, using a functional-style library:

List<String> userNames =, new Mapper<User, String>() {
  public String map(User user) {
    return user.getName();

Note that in this case, using the functional library actually ends up using an extra line, depending on how you format your curly braces. Either way, it’s not concise and it’s not pretty.


var userNames =\user -> user.Name)


userNames ={|user| user.Name}

In Ruby, there’s always more than one way to do things, so “map” and “collect” are synonyms for the exact same function. In addition, there are destructive versions named map! and collect! that modify the array in place instead of creating a copy.


userNames = [user.getName() for user in users]

This is an example of a list comprehension, which is basically map + filter + iteration built in to the language (though my guess is that it’s not the most efficient way to iterate a list, since it creates a new list . . . I could be wrong there, though). Python does also have a built-in map() method that takes a function and an iterable, but the idiomatic python way is to use a list comprehension. My Python knowledge is also letting me down here; I haven’t seen any language-level support for properties in Python like there is in Ruby or GScript, so I’m assuming that you’ll have to actually perform a method call here to get the name out.

Language Comparison – List Iteration

In my spare time I’ve started to learn Python (I’m working through the most excellent, and free, Dive Into Python book). Learning other languages, and how programmers work in other languages, is something that can improve your code regardless of the language you’re programming in. And of course, it can also be fun and interesting, and as someone who plays at least a peripheral role in the development of the GScript language, it’s always good to know what features and styles in other languages turn out to be useful.

In order for GScript to be viable on its own some day, it’ll need to be at least as useful as the languages that seem to have the most popularity today, so I figured it might be interesting to put together a small series of posts comparing how different languages solve similar problems. Since we’ve pushed the development of GScript largely to combat many of the deficiencies in Java, I’ll probably end up focusing on the problems that Java doesn’t solve well. To keep the comparisons from getting too crazy, I won’t include every language I could, and instead I’ll focus on some of the languages that one might consider for starting a modern web-development project: Java, GScript, Ruby, and Python.

For each post I’ll look at just one specific problem as a way to keep them shorter and more to the point. I’ll start the series off by looking at one of the most basic language operations: list iteration. List iteration and manipulation together tend to form a large component of any code base, so many languages have specialized constructs for doing them (and Lisp, of course, is literally all list processing). I’ll focus on just iteration here and look at various types of list manipulations in later posts. So what does it look like to iterate over a list of Strings and invoke a method on each item using the canonical list-iteration techniques in each language?


Java has several different ways to iterate over a list. The oldest is the basic C-style for loop:

for (int i = 0; i < list.size(); i++) {

Starting with Java 5, Java added in the Iterable interface and the ability to use a simpler for loop syntax:

for (String s : list) {

And lastly, some more functional-programming types occasionally attempt to abstract things even further and push the code into a more functional form, resulting in code like:

ListUtils.each(list, new ListProcessor<String>() {
  public void process(String s) {


GScript provides two different ways to iterate lists. It provides a for loop with syntax similar to the Java 1.5 syntax:

for (s in list) {

Starting with the Bedrock set of releases you could also use blocks to do:

list.each(\s -> foo(s))


GScript takes the name for blocks (and their general style) from Ruby, so unsurprisingly there are a lot of similarities here. While you can use for loops in ruby, no one actually does (except for Java programmers trying to learn Ruby). Instead, the canonical list-iteration pattern is to use the each method:

list.each {|s| foo s}

Ruby also allows you to easily apply an if statement to the end of a statement, making it easier to conditionally perform some action:

list.each{|s| foo s if s == "a"}

Doing that in either Java or GScript requires wrapping the print in an if statement instead.


You could also use a for loop in Python that looks similar to the GScript one:

for s in list:

That’s not the best example of Python’s list-processing capabilities, however. When we look into list manipulations, we’ll see that Python’s list comprehensions feature makes more complicated list manipulations relatively easy and concise, but they’re used for list transformation and not for iteration.

I’m not really an expert in either Python or Ruby, and I have to confess to not having tried out the Ruby examples (I don’t currently have a good Ruby-editing environment set up at home), so feel free to correct me if I’ve made any mistakes or missed out on some easier way to do things.

Why Java Needs Closures

There was a post by Bruce Eckel on Artima  this week that asked the question of whether or not closures would make Java less verbose, so it seemed like an apt time to put this up.

People tout closures as cure-alls for all sorts of things:  because they like functional programming or because it’s better suited to certain tasks, or maybe because they want to use it for control structures (so they don’t forget to close a file after reading it, say).  Honestly, I’m just sick of writing this same block of code over and over again:

Map<User, List<Claim>> claimsByUser = new HashMap<User, List<Claim>>();

for (Claim claim : someListOfClaims) {
  List<Claim> claims = someListOfClaims.get(claim.getUser());
  if (claims == null) {
    claims = new ArrayList<Claim>();
    claimsByUser.put(claim.getUser(), claims);

I’d much rather write something like:

var claimsByUser = someListOfClaims.partition(\claim-> claim.User)

Sometimes I feel like all my Java code devolves into a morass of for loops and angle brackets (I like generics, mostly, but without type inference they’re exceedingly painful). Even worse, it’s the same few for loops over and over again. You can write helper classes and methods to do things, and you can simulate closures using anonymous inner classes, but even then your code looks like:

Map<User, List<Claim>> claimsByUser = ListUtils.partition(someListOfClaims, new Partitioner<Claim, User>() {
  public User partition(Claim c) {
    return c.getUser();

Hardly the most elegant code on the planet.  If you had to read or modify the code, hopefully it’s obvious which one is easier to understand and easier to change.

There have been multiple closure proposals floated for inclusion in Java 7, and the one that looks like it’ll make it in is, like the generics implementation, a bit too complicated in the wrong ways. The arguments over exception and return handling within closures, along with debates about the scoping rules, have not (in my opinion) ended well, mainly (from what I can tell) due to a desire to be able to use closures to allow programmers to create new language-level control constructs, like the for loop added in Java 1.5. From my viewpoint, they’re silly questions to ask in the first place: a closure is a function, so a return statement within a closure just returns from that function. Returning from the containing scope just seems like madness and an invitation to serious confusion. Yes, it lets you define new control structures, and yes, new control structures can also simplify code, but I really think they should be two completely different features. Keep closures simple and understandable, with simple, consistent rules about scoping, return values, and exception handling. If people still demand better control structures, then make that a separate effort and implement those cleanly and simply.

While nothing’s been officially decided yet, I’m guessing that the two most likely outcomes are either 1) a confusing, over-engineered closures implementation or 2) no closures at all. And that’s just unfortunate; even some simple form of closures allows for a major simplification of routine data structure manipulations that both reduces code and makes code more clear.  And of course, closures are far more concise and usable if you add type inference in as well, but that’s another post. Just yet another reason why the world needs a language like GScript.