loading...

Defaultable Parameters in Ballerina

lankavitharana profile image Rajith ・3 min read

This is the second post from me on dev.to, actually, we did our 1.0 release pretty recently and got some free time on my part to do some blogging.

So let's dig into this cool ballerina feature. How many times you were wondering trying to invoke a method and what to pass into that function? of course, you should no what to pass, but there are occasions that you care about only a couple of parameters and rest of the parameters you just don't know what to do with. Personally, I faced such situations multiple times. Ballerina provides a cool way to deal with such scenarios. Basically, the function developer can provide the default value for the parameter so that the one who uses the function and invokes it can opt-out from providing a value for that parameter.

Let's take an example to get this clarified more. Below is a Ballerina function which has two string parameters, but the second parameter is an optional parameter.

public function encode(string content, string charset = "UTF-8") {

}

So when invoking the method you can simply choose to ignore that parameter altogether and override only when necessary, example invocations would be as follows

public function main() {
    // Invoke with first parameter, second will get defaulted to "UTF-8"
    encode("example");

    // Invoke with both parameters 
    encode("example", "UTF-16");

    // Invoke as named parameters
    encode("example", charset = "UTF-16");

    // Invoke as named parameters
    encode(content = "example", charset = "UTF-16");

    // Invoke as named parameters
    encode(charset = "UTF-16", content = "example");

}

If you have noticed, we can use both styles of invocation, where the argument to parameter mapping is deduced from the index of the argument in the invocation(the first argument to the first parameter and so on), as well as you can pass the arguments as named values. In the case of passing them as named values, the order doesn't matter. Cool right? :)

So the next question is to what extent do we support this? is it only simple literals you can use as default values? no, you can use any kind of expression as the default value. Below is an example where you invoke a function as the default value of a parameter.

import ballerina/io;

public function main() {
    // invoking without value
    invocationAsDefault();

    // invoking with value
    invocationAsDefault(abc(10));

}

public function invocationAsDefault(int asyncVal = abc(8)) {
    io:println(asyncVal);
}

public function abc(int a) returns int {
    return a + 5;
}

Another cool thing is, when you compose these expressions, you can use values of previous parameters in those expressions, below is a two-parameter function where the value of the first parameter is used to calculate the default value of the second parameter.

import ballerina/io;

public function main() {
    // Invoke without values
    paramExample(5);

    // Invoke with values
    paramExample(5, 20);
}

public function paramExample(int a, int b = a + abc(a)) {
    io:println(a + b);
}

public function abc(int a) returns int {
    return a + 5;
}

This behavior is similar across the board(that is even extern and interop functions also can have default parameters)

As you may know, Ballerina works in a non-blocking manner, which is an internal thing, but in effect, it means ballerina won't block threads unnecessarily. I mentioned that here because what I wanted to emphasize is you can even do non-blocking invocations as parameter default values.

Note - this post was written for the ballerina version 1.0.0.
Ballerina official site - https://v1-0.ballerina.io

There are so many other cool features in Ballerina. I will write more blog posts on those features, but for the time being, please give ballerina a whirl and see if you haven't already done so .. :) and don't forget to provide feedback :) as we are still evolving and would love the feedback...

Discussion

pic
Editor guide