DEV Community

Hasitha Aravinda
Hasitha Aravinda

Posted on • Originally published at bal.tips

Ballerina Identifiers: A Simple Guide for New Developers

Identifiers are names we give to elements in our code, like variables, functions, or types, to easily recognize and refer to them.

You'll find identifiers all over your code - for types, variables, functions, and more. Check out this picture showing all the identifiers in a typical Ballerina Service.

Identifiers are everywhere
Identifiers are everywhere - Source

Picking good identifiers is super important to make your code easy to read and understand. Every programming language has its own rules and guidelines for identifiers, and in this post, we'll dive into how to nail identifiers in Ballerina.

This is a summarized version of my blog post on Ballerina Identifiers - Best Practices and Use Cases. Head over there for more code examples and in-depth info.


✍️ Syntax

In Ballerina, identifiers have a few different syntax options:

  1. Standard Identifier: Starts with an ASCII letter, underscore, Unicode identifier character, or a Unicode code point escaped with \u{XXXX}. It can then be followed by any combination of characters, including digits. Can't use reserved words as they'll cause errors.
  2. Quoted Identifier: Begins with a single quote, allowing keywords and identifiers starting with digits. This helps avoid limitations of the standard syntax.
  3. Character Escaping: Use \u{XXXX} or \<Non-ASCII-CHAR> to include valid Unicode code points in identifiers. Some restrictions apply, as mentioned in the Ballerina Language Specifications.
  4. Qualified Identifier: To refer to elements in another module, use <module-prefix-identifier>:<identifier>. The module prefix must match the import declaration within the source file, and a colon separates it from the identifier without any whitespace.

Let's see some valid identifiers.

Standard Identifier Quoted Identifier Qualified Identifier
name '2invalid my\-variable
ageInYears '12345 bad\u{21}name
sales_tax_rate 'if \@hello
_isAvailable 'order id\ with\ spaces
MAX_ATTEMPTS 'class id\u{20}with\u{20}spaces

As you can see, Ballerina identifiers are quite flexible, supporting a wide range of combinations. This flexibility is particularly useful when working with data containing different languages and symbols, as it makes handling domain-specific terminology, non-ASCII characters, and even non-English languages much simpler.

In the following sections, we'll discuss some of the practical use-cases for Ballerina's versatile identifiers.

πŸ’‘ Few Use-Cases

  • Ballerina's design prioritizes Unicode support in identifiers, making it easy for programmers to use non-ASCII characters, domain-specific terminology, and non-English languages in their code.

    Writing Person record in different languages
    Writing Person record in different languages - View Source Code

  • Ballerina's flexible identifiers can be extended to support JSON values with special characters in the keys, making it easier to create matching identifiers that simplify data access and manipulation without complex transformations. This approach can be applied to other use-cases as well. Watch this video where I demonstrate working with JSON in Ballerina, showcasing how simple it is to handle such scenarios.

    Working with JSON Data with Special Characters in Keys - View Source Code

  • In Ballerina, use a single underscore _ to ignore unneeded values in certain contexts, but note that it only works for non-error values, as ignoring a value that could contain an error generates a compiler error.

Ignoring Values
Ignoring Values - View Source Code

πŸ’‘ Naming Conventions

Identifiers can be used in different language contexts, and depending on the context, there are generally accepted best practices for naming identifiers.

Identifiers Everywhere, But not a single one descriptive.
Identifiers Everywhere, But not a single one descriptive

  • Use descriptive identifiers to improve code readability.
    • Find a balance between length and clarity. This balance takes time to master.
  • Avoid abbreviations, except for widely-known ones.
  • Consider context and relevant conventions:
    • camelCase - for function/method names and parameters, variables (local, module level, configurable, etc.), record fields, and more.
    • PascalCase - for Type Definitions, Classes, Enums, etc.
    • UPPER_SNAKE_CASE - for Constants.
    • kebab-case - for Service and Resource path segments.
  • Understand the difference between public and non-public identifiers:
    • Choose public identifiers carefully for exposed APIs (service or client).
  • Be prepared to deviate from guidelines for specific requirements (e.g., OpenAPI/GraphQL/gRPC contracts) or when using non-English words, where camelCase or PascalCase may not apply.

πŸš€ Identifier Scopes

Ballerina identifiers have their own rules depending on the scope they're in. There are two main scopes: module-scope (usable in the module and, if public, outside too) and block-scope (limited to the block they're in). You can use the same name for both scopes within the same symbol space, but be careful not to overlap block-scoped ones with the same name or you'll get a compile error. For more info, check out my original post!


πŸŽ‰ Summary

Well, that's a wrap on our quick dive into Ballerina identifiers! I hope this discussion helped you learn a new language feature and gave you the confidence to handle special characters with ease. Remember, don't complicate things; use Ballerina for quick development. Maybe you can consider Ballerina for your next DIY integration.

Don't forget to check out my original blog post for more detailed explanations and code examples. Also, visit the ballerina.io website, as it has a lot of great resources to help you learn Ballerina.

You can meet Ballerina developers here.

Keep exploring, and happy coding with Ballerina!

Top comments (0)