Skip to content

Releases: ballerina-platform/ballerina-distribution

swan-lake-beta4-patch1

12 Oct 09:57
Compare
Choose a tag to compare
Pre-release
vswan-lake-beta4-patch1

[Gradle Release Plugin] - creating tag:  'vswan-lake-beta4-patch1'.

swan-lake-beta3

10 Oct 15:30
Compare
Choose a tag to compare
vswan-lake-beta3

[Gradle Release Plugin] - creating tag:  'vswan-lake-beta3'.

swan-lake-beta3-rc6

08 Oct 04:30
Compare
Choose a tag to compare
swan-lake-beta3-rc6 Pre-release
Pre-release
vswan-lake-beta3-rc6

[Gradle Release Plugin] - creating tag:  'vswan-lake-beta3-rc6'.

swan-lake-beta3-rc5

04 Oct 21:58
Compare
Choose a tag to compare
swan-lake-beta3-rc5 Pre-release
Pre-release
vswan-lake-beta3-rc5

[Gradle Release Plugin] - creating tag:  'vswan-lake-beta3-rc5'.

swan-lake-beta3-rc4

28 Sep 19:53
Compare
Choose a tag to compare
swan-lake-beta3-rc4 Pre-release
Pre-release
vswan-lake-beta3-rc4

[Gradle Release Plugin] - creating tag:  'vswan-lake-beta3-rc4'.

swan-lake-beta3-rc3

11 Sep 12:22
Compare
Choose a tag to compare
swan-lake-beta3-rc3 Pre-release
Pre-release
vswan-lake-beta3-rc3

[Gradle Release Plugin] - creating tag:  'vswan-lake-beta3-rc3'.

swan-lake-beta3-rc2

06 Sep 11:00
Compare
Choose a tag to compare
swan-lake-beta3-rc2 Pre-release
Pre-release
vswan-lake-beta3-rc2

[Gradle Release Plugin] - creating tag:  'vswan-lake-beta3-rc2'.

swan-lake-beta3-rc1

23 Aug 07:41
Compare
Choose a tag to compare
swan-lake-beta3-rc1 Pre-release
Pre-release

Overview of Ballerina Swan Lake Beta3

Language Updates

New Features

Introduction of the !is Operator

The !is operator has been introduced to check if a value does not belong to a given type. This is the negation of the is operator.

import ballerina/io;
 
public function main() {
   int|string? x = 10;
 
   if x !is () {
       io:println("int or string value: ", x);
   }
}
Inferring Types for Numeric Literals in Additive and Multiplicative Expressions

The type for numeric literals in additive and multiplicative expressions is now inferred from the contextually-expected type.

When the contextually-expected type for an additive or multiplicative expression is float, the type of a literal used as a sub expression is inferred to be float. Similarly, if the contextually-expected type is decimal, the type of the literal is inferred to be decimal.

float a = 10 + 3.0 + 5.0;
float b = 5 / 10.2;
decimal c = 10.0 * 3;
decimal d = 10 + 5 - 3.0;
Isolated Inference

The compiler now infers isolated for service objects, class definitions, variables, and functions in scenarios where if all of them explicitly specify an isolated qualifier, they would meet the requirements for isolated functions and isolated objects.

The following service and its methods are now inferred to be isolated.

import ballerina/http;
 
int defaultIncrement = 10;
 
service / on new http:Listener(8080) {
   private int value = 0;
 
   resource function get value() returns int {
       int value;
       lock {
           value = self.value;
       }
 
       lock {
           return value + defaultIncrement;
       }
   }
 
   resource function post increment(int i) {
       lock {
           self.value += i;
       }
   }
}

The compiler does not infer isolated for any constructs that are exposed outside the module.

Type Narrowing in the where Clause of a Query Expression/Action

The where clause in a query now narrows the types similar to if statements.

import ballerina/io;
 
public function main() returns error? {
   int?[] v = [1, 2, (), 3];
   int total = 0;
   check from int? i in v
       where i is int
       do {
           // Type of `i` is narrowed to `int`.
           total += i;
       };
   io:println(total); // Prints 6.
}

Improvements

Enum Declarations with Duplicate Members

Enum declarations can have duplicate members.

For example, the following declarations where both LiftStatus and TrailStatus have the same OPEN and CLOSED members are now allowed.

enum LiftStatus {
   OPEN,
   CLOSED = "0",
   HOLD
}
 
enum TrailStatus {
   OPEN,
   CLOSED = "0"
}

However, it is an error if the same enum declaration has duplicate members. Similarly, it is also an error if different enums initialize the same member with different values.

string:Char as the Static Type of String Member Access

The static type of the member access operation on a value of type string has been updated to be string:Char instead of string.

public function main() {
   string str = "text";
 
   // Can now be assigned to a variable of type `string:Char`.
   string:Char firstChar = str[0];
}
Directly Calling Function-typed Fields of an Object

Fields of an object that are of a function type can now be directly called via an object value using the method call syntax.

class Engine {
   boolean started = false;
  
   function 'start() {
       self.started = true;
   }
}
 
class Car {
   Engine engine;
 
   function () 'start;
 
   function init() {
       self.engine = new;
       // Delegate `car.start` to `engine.start`.
       self.'start = self.engine.'start;
   }
}
 
public function main() {
   Car car = new;
   car.'start(); // Call the function via the object field.
}
Tuple to JSON Compatibility

A tuple value whose members are JSON compatible can now be used in a context that expects a JSON value.

[string, int, boolean...] a = ["text1", 1, true, false];
// Now allowed.
json b = a;
Error Return in the init Method of a Service Declaration

Previously, the init method of a service declaration could not have a return type containing an error. That restriction has been removed with this release.
If the init method of a service declaration returns an error value, it will result in the module initialization failing.

import ballerina/http;
 
service / on new http:Listener(8080) {
   function init() returns error? {
       // Return an error for demonstration.
       // This will result in module initialization failing.
       return error("Service init failure!");
   }
}
Using check in Object Field Initializers

check can now be used in the initializer of an object field if the class or object constructor expression has an init method with a compatible return type (i.e., the error type that the expression could evaluate to is a subtype of the return type of the init method).

If the expression used with check results in an error value, the init method will return the error resulting in either the new expression returning an error or the object constructor expression resulting in an error.

import ballerina/io;
 
int? value = ();
 
class NumberGenerator {
   int lowerLimit;
 
   // `check` can be used in the field initializer
   // since the `init` method's return type allows `error`.
   int upperLimit = check value.ensureType();
 
   function init(int lowerLimit) returns error? {
       self.lowerLimit = lowerLimit;
   }
}
 
public function main() {
   NumberGenerator|error x = new (0);
 
   if x is error {
       io:println(x);
   }
}
Wildcard Binding Pattern Support in Variable Declarations

The wildcard binding pattern can now be used in a variable declaration with a value that belongs to type any.

import ballerina/io;
 
float _ = 3.14;
var _ = io:println("hello");

Using the wildcard binding pattern when the value is an error will result in a compilation error.

var _ = error("custom error"); // Compilation error.
Relaxed Static Type Requirements for == and !=

Previously, == and != were allowed only when both operands were of static types that are subtypes of anydata. This has now been relaxed to allow == and != if the static type of at least one operand is a subtype of anydata.

error? x = ();
 
// Now allowed.
if x == () {
 
}
Relaxed Query Expression Keywords

Identifiers that are keywords in a query expression context (where, join, order, by, equals, ascending, descending, limit, outer, and select) can now be used as ordinary identifiers outside query contexts. i.e., they are no longer required to be quoted identifiers.

// Now allowed. No longer required to use a quoted identifier (`'limit`).
int limit = 5;
// Now allowed. No longer required to use a quoted identifier (`string:'join()`).
string b = string:join(" ", "hello", "world!"); 

Bug Fixes

  • In a stream type stream<T, C>; the completion type C should always include nil if it is a bounded stream. A bug where this was not validated for stream implementors has been fixed.
class StreamImplementor {
   public isolated function next() returns record {|int value;|}|error? {
       return;
   }
}
 
stream<int, error> stm = new (new StreamImplementor()); // Will now result in an error.
  • Resource methods are no longer added to the type via object type inclusions. This was previously added even though resource methods do not affect typing.
service class Foo {
   resource function get f1() returns string {
       return "foo";
   }
 
   function f2() returns int => 42;
}
 
// It is no longer required to implement the `get f1` resource method.
service class Bar {
   *Foo;
 
   function f2() returns int => 36;
}
  • A bug in string unescaping of unicode codepoints > 0xFFFF has been fixed.
import ballerina/io;
 
public function main() {
  string str = "Hello world! \u{1F600}";
  io:println(str);
}

The above code snippet which previously printed Hello world! ὠ0 will now print Hello world! 😀.

  • A bug in escaping NumericEscape has been fixed.
import ballerina/io;
 
public function main() {
  string str = "\\u{61}pple";
  io:println(str);
}

This code snippet, which previously printed \u0061pple will now print \u{61}pple.

  • A bug that resulted in NumericEscape in the template string not being interpreted literally has been fixed.
import ballerina/io;
 
public function main() {
  string str = string `\u{61}pple`;
  io:println(str);
}

The code snippet above, which previously printed \u0061pple will now print \u{61}pple.

  • A bug that resulted in self-referencing not being detected when referenced via a let expression or a constant reference expression has been fixed.

The following will now result in errors.

const int INTEGER = INTEGER; // Compilation error.

public function main() {
    string s = let string[] arr = [s] in arr[0]; // Compilation error.
}
  • Type narrowing is now reset on any assignment to a narrowed variable. Previously, type narrowing was not reset if the static type of the new value was a subtype of the narrowed type. This was a deviation from the specification.
public function main() {
    int|string v = 0;

    if v is int {
        int x = v; // Valid.

    ...
Read more

swan-lake-alpha5.11

28 Jul 11:14
Compare
Choose a tag to compare
vswan-lake-alpha5.11

[Gradle Release Plugin] - creating tag:  'vswan-lake-alpha5.11'.

swan-lake-alpha5.10

13 Jul 16:50
Compare
Choose a tag to compare
vswan-lake-alpha5.10

[Gradle Release Plugin] - creating tag:  'vswan-lake-alpha5.10'.