Skip to content

Latest commit

 

History

History
477 lines (340 loc) · 15.9 KB

release-notes-1.0.0-alpha.md

File metadata and controls

477 lines (340 loc) · 15.9 KB

Breaking Changes

Breaking Language Changes

Builtin library

The builtin module has been removed. Some of the functionalities provided by the builtin library is now provided by the newly added lang library.

  • The freeze() builtin method has been replaced with the cloneReadOnly() lang library function. cloneReadOnly() can be called only on variables of type anydata and it creates and returns a clone of the value that has been made immutable (for non-simple basic types).

Previous Syntax

map<string> m2 = m.freeze();  

New Syntax

map<string> m2 = m.cloneReadOnly();
  • The convert() builtin method has been replaced with the constructFrom() lang library function. constructFrom() can only be called a type descriptor T where the T is a subtype of anydata. It accepts an anydata value as an argument and returns a value of type T constructed using a deep copy of the provided argument. If the construction fails, it returns an error.

Previous Syntax

json j = { name : "tom", age: 2};
Person|error p = Person.convert(j);

New Syntax

json j = { name : "tom", age: 2};
Person|error p = Person.constructFrom(j);
  • The following behaviours which were previously associated with the convert() method is now provided by the lang library functions of the relevant types.
  • Previously, convert() was used to parse string literals. Now, the lang.int, lang.float and lang.decimal modules have a fromString() function which accepts a string literal and parses it.

Previous Syntax

int|error x = int.convert(“100”);

New Syntax

import ballerina/lang.’int; // Need to import `lang.int`

int x =int:fromString(“100”);
  • When invoked on the string typedesc, convert() returned a string representation of the value. Now the lang.value module provides a toString() function which returns a human-readable string representation of a value.

Previous Syntax

json person = {“name:John”, “age:25};
string|error str = string.convert(person);

New Syntax

json person = {“name:John”, “age:25};
string str = person.toString();
  • The stamp() method has been removed.

Maps and Records

  • The semantics of the {, } delimiters and {|, |} delimiters have changed. A record type descriptor written using the {| and |} delimiters defines a record type that only accepts mapping values with the same fields as the ones described. A record type descriptor written using the { and } delimiters define a record type which additionally allows pure type fields apart from the fields described. i.e., record {} is equivalent to record {| anydata…; |}.

Previous Syntax

// Open record with a field `a`. It additionally allows
// `anydata|error` fields.
type Foo record {
   string a;
};

// Open record with a field `a`. It additionally allows
// `int` fields.
type Bar record {
   string a;
   int...;
};

// Closed record which only allows a `string` field named `a`.
type Baz record {|
   string a;
|};

New Syntax

// Open record with a field `a`. It additionally allows
// `anydata` fields.
type Foo record {
  string a;
};

// Open record with a field `a`. It additionally allows
// only `int` fields.
type Bar record {|
  string a;
  int...;
|};

// Closed record which only allows a `string` field named `a`.
type Baz record {|
  string a;
|};
  • The default record rest field type has been changed to anydata from anydata|error.
  • The syntax to specify expressions as keys in the mapping constructor has changed. Expressions need to be enclosed in [] (e.g., [expr]).

Previous Syntax

map<string> m = { getString(): "value" };

New Syntax

map<string> m = { [getString()]: "value" };
  • String literals can now be used as keys in the mapping constructor for a record. The key for a rest field should be either a string literal or an expression in the mapping constructor (i.e., cannot be an identifier).

Previous Syntax

type Foo record {
   string bar;
   int...;
};

Foo f = { bar: "test string", qux: 1 }; // `qux` is a rest field

New Syntax

type Foo record {|
   string bar;
   int...;
|};

Foo f = { bar: "test string", "qux": 1 }; // `qux` is a rest field
  • Mapping values are now iterable as sequences of their members (values) instead of sequences of key-value pairs. A lang library function entries() is available to retrieve an array of key-value pairs for a mapping value.

Previous Syntax

foreach (string, int) (k, v) in m {
   io:println("Key:   ", k);
   io:println("Value: ", v);
}

New Syntax

// Iterating values.
foreach int v in m {
   io:println("Value: ", v);
}

// Iterating entries.
foreach [string, int] [k, v] in m.entries() {
   io:println("Key:   ", k);
   io:println("Value: ", v);
}

Arrays and Tuples

  • The requirement on array element types to have an implicit initial value to allow declaring variable-length arrays has been removed. Instead, when a value is being added to the array at runtime, and the index is greater than the length of the list and the element type does not have a filler value, it would result in a panic.

Previous Syntax

(int|string)[] arr = []; // Fails at compile time.
arr[1] = 1;

New Syntax

(int|string)[] arr = [];
arr[1] = 1; // Fails at runtime.
  • Tuple types now use brackets instead of parentheses.

Previous Syntax

(int, string) t = (1, "hello world");

New Syntax

[int, string] t = [1, "hello world"];
  • Tuple types now support rest descriptors. Therefore, following syntax is valid now.
[int, string, boolean...] t = [1, "hello world", true, true];
[int...] t3 = [1, 2];

Objects

  • Object outside method definitions are no longer allowed. All object function definitions need to be specified within the object itself. The following syntax is invalid now.
type Foo object {
   int code = 0;

   function printCode();
};

function Foo.printCode() {
   // print code
}

Functions and Methods

  • Arguments for required parameters of a function can now also be passed as named arguments, while arguments for defaultable parameters can be passed as positional arguments. To avoid ambiguity, all named arguments need to be specified after the positional arguments.
  • Parameters of a function can now be marked public, and only arguments to such parameters can be passed by name when invoking a function from an imported module. These arguments can still be passed as positional arguments.

Error Type and Constructor

  • The error detail type must now belong to the detail type defined in the error lang library.
public type Detail record {|
   string message?;
   error cause?;
   (anydata|error)...;
|};
  • The error constructor now accepts detail fields as individual named arguments as opposed to accepting a single mapping as the detail argument. Previous Syntax
Detail detail = { message: "error message", code: 1100 };
error e = error("error reason", detail);

New Syntax

error e = error("error reason", message = "error message", code = 1100);

Annotations

  • Annotation declaration syntax and attachment points have been revised. Annotations can now be declared to be available only at compile time (source only annotations) or at both compile-time and runtime.

Previous Syntax

annotation<service> annot Foo;

New Syntax

annotation Foo annot on service;

Expressions

  • Integer range expressions now return objects belonging to the iterable abstract object type instead of lists (arrays).
  • Field access for records, objects and json has changed. Field access can be used to access the fields of an object or required fields of a record. Field access on a lax (json|map<json>) typed variable now returns json|error. The field access operator does not lift nil now.
  • Member access is allowed with lists and subtypes of optional mappings. Nil lifting is supported in the latter case.
  • The error lifting operator (!) has been removed. Error lifting now happens only with field or optional field access for lax types.
  • Calls with start are now considered actions, and as a result are not allowed within expressions.
  • Delimited identifier syntax has been changed.
string ^"1" = "identifier one";
string ^"identifier two" = "identifier two";

New Syntax

string '1 = "identifier one";
string 'identifier\ two = "identifier two";
  • The untaint unary operator has been replaced by an annotation to mark a value as trusted.

Previous Syntax

var untaintedValue = untaint taintedValue;

New Syntax

var untaintedValue = <@untainted> taintedValue;

What's new in Ballerina 1.0.0-alpha

Language

  • A set of modules which contain the functions associated with the basic types. These modules are referred to as the lang library. Each basic type has a corresponding lang library module. Additionally, there is also the lang.value module, which holds functions common for all the types. Following is the list of lang library modules.

    • ballerina/lang.value
    • ballerina/lang.array for basic type list
    • ballerina/lang.decimal for basic type decimal
    • ballerina/lang.error for basic type error
    • ballerina/lang.float for basic type float
    • ballerina/lang.future for basic type future
    • ballerina/lang.int for basic type int
    • ballerina/lang.map for basic type mapping
    • ballerina/lang.object for basic type object
    • ballerina/lang.stream for basic type stream
    • ballerina/lang.string for basic type string
    • ballerina/lang.table for basic type table
    • ballerina/lang.typedesc for basic type typedesc
    • ballerina/lang.xml for basic type xml
  • The basic type handle has been added. A handle value is a reference to storage managed externally to a Ballerina program. Handle values are useful only in conjunction with functions that have external function bodies; in particular, a new handle value can be created only by a function with an external function body.

  • The error reason is now optional if the reason can be inferred based on the contextually expected type.

type Detail record {
   int code;
};

const FOO = "foo";

type FooError error<FOO, Detail>;

FooError e1 = error(FOO, code = 3456);
FooError e2 = error(code = 3456); // Also valid now, reason is set as "foo"
  • A unary operator typeof has been introduced to retrieve a typedesc value for the runtime type of a value.
typedesc t = typeof valueExpr;
  • A binary operator .@ has been introduced to access annotation values at runtime.
annotation Foo annot on service;
typedesc t = typeof serviceValue;
Foo? fooAnnot = t.@annot;
  • Expressions are now allowed as default values for function parameters.

  • The concept of lax typing has been introduced, allowing less stricter static typing for types identified as lax. With lax typing, some of the static typing checks are moved to the runtime, resulting in error returns at runtime instead. With this release, json and map<T> where T is lax are considered as lax.

  • An optional field access operator ?. has been introduced to access possibly undefined mapping members. Optional field access on lax types may return error, if applied to a non-mapping value.

Runtime

We are introducing a brand new implementation (jBallerina) of the Ballerina language spec that targets the JVM. The jBallerina compiler produces an executable jar file for a Ballerina program by directly transforming Ballerina sources to Java bytecode. With jBallerina, we are deprecating and removing our previous Ballerina runtime implementation (BVM). The jBallerina comes with significant performance improvements over the BVM.

Java Interoperability

Java interoperability is a key feature in jBallerina that allows you to call Java code from Ballerina. It also enables you to embrace the capabilities of Ballerina for new projects while utilizing existing Java libraries that you or your company invested in for years.

Project Structure & Build Tools

  • Ballerina project structure should match the following.
project-name/
- Ballerina.toml
- src/
-- mymodule/
--- Module.md  	<- module level documentation
--- main.bal   	<- Contains default main method.
--- resources/ 	<- resources for the module (available at runtime)
--- tests/     	<- tests for this module (e.g. unit tests)
---- testmain.bal  <- test file for main
---- resources/	<- resources for these tests
- tests/       	<- integration tests
-- integration.bal <- integration test file
-- resources/  	<- integration test resources
- target/     	<- directory for compile/build output
-- bin/       	<- Executables will be created here
-- balo/      	<- .balo files one per built module
--- mymodule.balo  <- balo object of module1
-- cache      	<- BIR, JAR cache directory

export BALLERINA_DEV_STAGE_CENTRAL=true
  • To create a new project with a hello world use new command to initialize a new directory $ ballerina new <project-name>

  • To create a module use create command inside the project $ ballerina create <modulename> [-t main|service]

  • If you are building a library use compile command to generate a balo to push to central $ ballerina compile

  • To create an executable use the build command $ ballerina build

  • To run the executable use run command $ ballerina run mymodule-executable.jar

Ballerina Central

  • Supports pushing of Ballerina modules with native Java libraries.

Standard Library

  • Revamped NATS connector to support both NATS and Streaming Servers.
  • Introduce StdLib module wise errors as a replacement for the builtin error.
  • Eg: Ballerina HTTP Error types include http:ClientError, http:ListenerError, http:ClientAuthError etc.
  • Introduce capability to engage custom providers and handlers for inbound/outbound authentication
  • Introduce OAuth2 inbound authentication
  • Introduce own modules for different authentication mechanisms (JWT, LDAP, OAuth2 etc.)
  • Improve LDAP APIs by decoupling usage with auth provider
  • Introduce support for consumer services with data binding, queue-groups, different start position types etc.
  • Introduce prior knowledge support to the HTTP/2 client
  • Add flow control support to HTTP/2 client and server
  • Data binding support for RabbitMQ connector. The supported types include int, float, string, json, xml, byte[] and records.
  • Transaction support in RabbitMQ broker and added Ballerina local transaction support for the module. Ballerina RabbitMQ local transactions follow the RabbitMQ broker semantics transaction model.
  • Introduce XSL transformation support
  • Databinding, transaction, SSL and OnError resource support for ActiveMQ Artemis connector
  • Revamp of the Message object in the JMS connector
  • Introduce "system" APIs to perform system bound file operations such as create file, create directory, move directory, rename file, get file metadata, copy file etc.
  • H2 and MySQL database client modules have been discontinued. JDBC client module can be used to interact with relational databases.

IDEs & Language Server

IntelliJ IDEA Plugin

  • Introduce Ballerina home auto detection capability.
  • Introduce Ballerina sequence diagram view.
  • Revamp debugger using DAP(Debugger Adapter Protocol) client.
  • Introduce in-place renaming support.
  • Add language server based signature help.

Tooling

  • Ballerina Formatter: Ballerina source formatting CLI tool.
  • OpenAPI to Ballerina generator CLI tool.
  • Ballerina to OpenAPI generator CLI tool.
  • OpenAPI validator compiler plugin.
  • Introduce Debug Adapter Protocol implementation.