Swan Lake Beta4

Overview of Ballerina Swan Lake Beta4

This is the fourth Beta release in a series of planned Alpha and Beta releases leading up to the Ballerina Swan Lake GA release.

It introduces the new language features planned for the Swan Lake GA release and includes improvements and bug fixes done to the compiler, runtime, standard library, and developer tooling after the Swan Lake Beta3 release.

Updating Ballerina

If you are already using Ballerina, you can use the update tool to directly update to Ballerina Swan Lake Beta4 as follows.

To do this, first, execute the command below to get the update tool updated to its latest version.

bal update

If you are using an update tool version below 0.8.14, execute the ballerina update command to update it. Next, execute the command below to update to Swan Lake Beta4.

bal dist pull slbeta4

Installing Ballerina

If you have not installed Ballerina, then download the installers to install.

Language updates

New features

Support for numeric operations with operands of optional numeric types

Updated unary expressions (+, -, and ~), multiplicative expressions, additive expressions, shift expressions, and binary bitwise expressions to be used with operands of optional numeric types. If the static type of an operand is an optional numeric type, the static type of the result will also be an optional numeric type.

The examples below are allowed now.

Support for accessing optional fields of a record using field access

Updated optional fields of records, which are of types that do not include nil to be accessed using field access expressions.

However, the below is still not allowed since the field's type includes nil.

If the static type of the expression on which the access is done is a non-lax union type, field access is allowed only if it is a union of record types and

  • each member of the union has a required field with the specific field name or
  • each member of the union has either a required field or an optional field with the specific field name, and the type of the field in each record type does not include nil


Restrictions when calling a function or a method in a match guard

Introduced restrictions for when a function or a method is called in a match guard to ensure that the match guard does not mutate the value being matched.

A function or method call is allowed now in a match guard only if it meets one of the conditions below.

  • the type of the expression following match is a subtype of readonly or
  • the function/method is isolated and the types of any and all arguments are subtypes of readonly

The below will now result in compilation errors.

Improved support for unreachability

Improved the unreachability analysis of if-else statements and while statements. Constant conditions that are known to be either true or false at compile-time are now considered in the unreachability analysis.

The conditions below are taken into consideration in the analysis of unreachability.

  1. If a statement block is unreachable, then every statement in it is unreachable.
  2. The if statements with constant conditions are not errors except insofar as they lead to statements being unreachable.
  3. An is expression is constantly true if the static type of the expression is a subtype of the type against which the check is done.
  4. Calling a function with a return type of never cannot complete normally making subsequent code unreachable.

The below is another example.

Type narrowing following an if statement without an else block if the if statement block cannot complete normally

Narrowed the types following an if statement without an else block, if the if statement block cannot complete normally by building on the improvements introduced to the unreachabillity analysis.

This narrowing may lead to other compilation errors since the static type of the variable will now be a narrowed type.

Restrictions on assignments to narrowed variables within loops

Stopped the possibility to assign a value to a variable that was narrowed outside the statement within a while statement or a foreach statement. Unless the loop terminates after the assignment (i.e., at the end of the loop body and at every continue statement), there must be no possibility that a narrowed variable to be assigned.

The example below which previously resulted in a runtime panic will now result in a compilation error.

Change in expected return statements in a function with an optional type as the return type

Updated a function having an optional type that is not a subtype of error? as the return type to explicitly return a value. A warning is emitted when such a function does not explicitly return a value and falls off at the end of the function body.

Bug fixes and breaking changes

  • Disallowed the trailing dot format of the floating-point literal to avoid lexical ambiguity.

  • Disallowed intervening white spaces in the qualified identifier to avoid a parsing ambiguity between the ternary conditional expression and qualified identifier.

    With this, x ? a : b:c will now be parsed as x ? a : (b:c) since the colon with spaces is interpreted only as part of a conditional expression.

  • Fixed a bug that resulted in hash collisions not being handled correctly in table values.

    The above code snippet, which previously printed true will now print false.

  • Disallowed object type inclusions with an object that has private fields or members.

  • Fixed a bug that resulted in compilation errors not being emitted for invalid xml template expressions.

  • Fixed a bug that resulted in compilation errors not being emitted for duplicate fields written with escape sequences in the mapping constructor.

  • Updated the xml:createElement to accept the attribute map as the second argument.

  • Updated the xml:get function’s return type to return the exact type T when the xml sequence is of type xml<T>.

  • Updated the table:map function’s function argument func and the return type to work with subtypes of mapping types instead of any type.

  • Corrected a few deviations in the lang.error module according to the language specification. The CallStack class and CallStackElement records have been removed. Now, a stack frame is represented by an error:StackFrame object.

    Prior to Swan Lake Beta4, the error:stackTrace() function returned an error:CallStack object which had the structure below which was a deviation from the specification.

    This has now been fixed, and it is no longer possible to retrieve an error:CallStack object or directly access the callStack array as shown below.

    The error:stackTrace function now returns an array of StackFrame objects.

  • Made the return type of the error:detail function in the lang.error module a subtype of readonly. It is the intersection of readonly and the detail type of the error.

  • Fixed a deviation in the stream:next function’s stream argument name. The name has been changed from strm to stm.

  • Fixed a bug in array:sort, which was sorting the original list. The function now returns a new sorted array. The original array remains unchanged.

  • Changed the name of the argument to transaction:setData() from e to data. Moreover, changed the static type of the argument to transaction:setData() and the return type of lang.transaction:getData() to readonly. They were previously of type (any|error) & readonly and even this change would accept/return the same set of values.

  • Updated the float:min() and float:max() functions to return float:NaN if an argument is float:NaN.

  • Fixed a bug in the decimal:fromString() function, which allowed parsing a string that matched the HexFloatingPointLiteral. It now returns an error.

  • Fixed a bug in the float:fromString() function allowed parsing a string that had matched a DecimalFloatingPointNumber with FloatingPointTypeSuffix. This will now return an error.

  • Updated the float:fromHexString() function to return an error if the provided string argument does not match a HexFloatingPointLiteral.

  • Fixed a spec deviation in the int:toHexString, which was causing it to convert negative values to a positive number before converting to a hexadecimal string.

  • Fixed a deviation in the lang.error RetryManager and DefaultRetryManager objects' shouldRetry method argument type. The type has been changed from error? to error.

  • Updated the attempting to use an out of range float value where the applicable contextually-expected type is float to result in a compile-time error.

  • Fixed the spec deviations related to identifying the types of numeric literals.

    If the numeric literal does not include the float type suffix or the decimal type suffix and if it is not a hex floating-point literal, the type of the numeric literal will be based on the rules below.

    1. If the literal is a floating-point literal, then the possible basic types in order of preference are [float, decimal]. Otherwise, they are [int, float, decimal].
    2. If there is a contextually-expected type C and there is an intersection between C and the possible numeric basic types identified above, use the most preferred such type.
    3. Otherwise, use the most preferred possible basic type.

    The example below now results in a compile-time error since the type of the literal is considered to be float and Foo does not contain float 2.

To view bug fixes, see the GitHub milestone for Swan Lake Beta4.

Runtime updates


Improved error messages on a type conversion failure

Updated the detailed error messages to be given on a type conversion failure narrowing down the specific location of errors in the structural types. A maximum number of 20 errors are shown at a time.

For example, the code below

now gives the error below.

Improvement in the runtime error creator API

Improved the runtime Java error creator API to get a BMap as the details parameter.

New runtime Java APIs

API to access information of type inclusions at the runtime

Introduced a new API to retrieve the type IDs of the given io.ballerina.runtime.api.types.ObjectType.

API to retrieve the constituent types of an intersection type

Introduced a new API to provide the list of constituent types of a given io.ballerina.runtime.api.types.IntersectionType.

Bug fixes

Removed supporting the single-quote to mark the boundary of a JSON string value

Stopped the JSON parser supporting single quotes to mark the boundaries of a string to comply with the JSON specification. Only double quotes are supported now.

Throw unused configurable value warnings as errors

When there is a configuration value provided in the Config.toml file or a command-line argument that does not match with the existing configurable variables, it will fail at runtime with an error instead of a warning.

For example, if you have the below in the main.bal file,

and the below in the Config.toml file,

then, it will fail with the errors below.

To view bug fixes, see the GitHub milestone for Swan Lake Beta4.

Standard library updates

New features

mysql package

  • Introduced failover and retry support
  • Added noAccessToProcedureBodies options

log package

  • Introduced the setOutputFile function to write the log output to a file

http package

  • Introduced request and request error interceptors

grpc package

  • Introduced Protobuf Any type support


sql package

  • Improved the queryRow() function to support union return types
  • Improved the parameterized query to support the escaped backtick as insertions

log package

  • Added error:StackFrame[] as a key-value pair type

http package

  • Relaxed the data-binding restriction for status codes without content
  • Changed the Listener.getConfig() API to return an InferredListenerConfiguration

websub package

  • Updated to not change the generated unique-service-path after compilation


  • Marked all the standard library services as distinct
  • Removed all the info logs printed from the listeners

Bug fixes

To view bug fixes, see the GitHub milestone for Swan Lake Beta4.

Developer tools updates

New features

Language server

  • Added document symbol support
  • Added the pull module code action to pull locally unavailable Ballerina packages from Ballerina Central
  • Added a new code action to add an explicit return statement where required
  • Added a new code action to create a readonly clone
  • Added the ignore unused variables code action
  • Added the remove unreachable statement code action
  • Added dynamic capability registration support for extended services

To view bug fixes, see the GitHub milestone for Swan Lake Beta4.


  • Added support to debug pause instructions. With this support, any running Ballerina programs can be suspended immediately at the current execution line of the program.
  • [Preview Feature] Introduced Ballerina code completion support in the Visual Studio Code debug console. Now, a context-aware completion list will be suggested automatically for Ballerina expressions in the VSCode evaluation window.
  • Added string template support for debug logpoints. Now, you can interpolate expressions within debug logpoint messages by using the ${} syntax so that the debug logpoints can be used to log state variable information without suspending the program.

Bug fixes

To view bug fixes, see the GitHub milestone for Swan Lake Beta4 of the repositories below.