New "Unified Class Syntax coming in Oxygene 8.4

Another area where we're making some significant improvements for the upcoming Elements 8.4 release is the Oxygene language itself.

We haven't made any drastic changes to Oxygene in a while, but we have several new features planned, one of which I want to look at today: Unified Class Syntax.

Very different from C# and Swift, Oxygene has always strongly separated the declaration of a class (or a similar type, such as a record or an interface) from its implementation. This has grown mostly from historical reasons, because back when Pascal was invented, compilers were a lot simpler, and needed to be able to fully know what all types looked like, before processing the actual code.

While a lot can be said for keeping declaration and implementation separated from each other, working in Swift and C# over the past few years has really made me appreciate how much simpler it can be to write code when that is not necessary.

So we decided to bring this capability to Oxygene as well – optionally, of course.

Starting with version 8.4 (and this is available in the current beta drops), you can now choose to include a method's body right at the point of declaration:

type
  Foo = public class
  public

    method FooIt;
    begin
      writeLn('Foo!');
    end;

  end;

The syntax extension is simple and unambiguous: any method-like declaration (methods, constructors, finalizers) can now be followed by either the begin or the require keyword, to provide the implementation right there in place. (var is not allowed, because it would be ambiguous with a class-level variable section. Plus, you should be declaring your variables inline anyway ;)).

By default, methods will still get their visibility based on the section they are declared in (FooIt above will be public). But visibility specifiers can also be provided as directives on individual methods, to override this:

type
  Foo = public class
  public

    method FooIt;
    begin
      FooHelper();
    end;

    method FooHelper; private;
    begin
      writeLn('Foo!');
    end;

    method BarIt;
    begin
      writeLn('Bar!');
    end;

  end;

This makes FooHelper() private, but allows it to be kept grouped with its related methods without needlessly requiring additional visibility sections.

What about interface & implementation?

I'm glad you asked. If all members of all classes in a file are implemented inline (or in cases where there are simply no implementations required, such as a file that declares only interfaces or enums), the separate interface and implementation sections are now optional, and the two keywords can simply be omitted. This is now a fully valid Oxygene source file:

namespace Simple;

type
  SimpelClass = public class
  public
    method DoIt;
    begin
    end;
  end;

end.

Optional Only

Remember, this new syntax is entirely optional – and we know it will be controversial ;).

In many cases, Oxygene's separation of declaration and implementation can be a real boon, and in those cases you can (and should) continue using the old syntax, of course – it will be supported indefinitely and is not deprecated. In many other cases, we believe the new syntax will really make it quicker and easier to write and read Oxygene code, and avoid the extra overhead of maintaining the two sections separately.

As one user on the beta put it:

"This looks so clean. Now I can't open any of my source files without wanting to change them all to the new syntax immediately!" ;)

Give it a try in the new Beta, and let us know what you think!