From 18262de3d8d7ae96eac30dbedcbec855f5a66a60 Mon Sep 17 00:00:00 2001 From: MaryamZi Date: Fri, 22 Nov 2024 11:01:45 +0530 Subject: [PATCH] Add a BBE for singleton types --- examples/singleton-types/singleton_types.bal | 64 +++++++++++++++++++ examples/singleton-types/singleton_types.md | 19 ++++++ .../singleton-types/singleton_types.metatags | 2 + examples/singleton-types/singleton_types.out | 5 ++ 4 files changed, 90 insertions(+) create mode 100644 examples/singleton-types/singleton_types.bal create mode 100644 examples/singleton-types/singleton_types.md create mode 100644 examples/singleton-types/singleton_types.metatags create mode 100644 examples/singleton-types/singleton_types.out diff --git a/examples/singleton-types/singleton_types.bal b/examples/singleton-types/singleton_types.bal new file mode 100644 index 0000000000..3cffafbead --- /dev/null +++ b/examples/singleton-types/singleton_types.bal @@ -0,0 +1,64 @@ +import ballerina/io; + +// The `SwitchStatus` type is a union type of two singleton types +// defined using string literals, which are simple constant expressions. +type SwitchStatus "on"|"off"; + +// The `shouldToggleSwitch` function has two parameters of the `SwitchStatus` type, +// restricting the arguments to be either "on" or "off". Trying to pass as an argument +// a value that cannot be guaranteed to be either "on" or "off" will result +// in a compile-time error. +function shouldToggleSwitch(SwitchStatus currentStatus, SwitchStatus newStatus) + returns boolean { + return currentStatus != newStatus; +} + +// The type of the `STATUS_OFF` constant is the singleton type containing only +// the "off" value. +const STATUS_OFF = "off"; + +// The type of the `DEFAULT_CONFIG` constant is the singleton type containing only +// an immutable mapping value with exactly two fields: a `name` field with the value +// "default" and a `status` field with the value "off". +const DEFAULT_CONFIG = { + name: "default", + status: STATUS_OFF +}; + +public function main() { + // The `shouldToggleSwitch` function can be called only with "on" or "off" as arguments. + boolean b1 = shouldToggleSwitch("on", "off"); + io:println(b1); + + // The type of `arg1` is the singleton type containing only the "off" value. + "off" arg1 = "off"; + + // A constant can be used as a singleton type. + // The type of `arg2` is also the singleton type containing only the "off" value. + // On the left-hand side, `STATUS_OFF` is used as a type. + // On the right-hand side, `STATUS_OFF` is used as a value. + STATUS_OFF arg2 = STATUS_OFF; + + boolean b2 = shouldToggleSwitch(arg1, arg2); + io:println(b2); + + // An immutable mapping value that has exactly the same fields as the + // `DEFAULT_CONFIG` constant. + map & readonly mv1 = { + name: "default", + status: "off" + }; + + // An immutable mapping value that is not the same as the `DEFAULT_CONFIG` + // value since it has "on" as the value for the `status` field. + map & readonly mv2 = { + name: "default", + status: "on" + }; + + // The `DEFAULT_CONFIG` constant is used as a type in the `is` check. + // Since it is a singleton type, the `is` check will evaluate to true + // only for an immutable value that has exactly the same fields. + io:println(mv1 is DEFAULT_CONFIG); + io:println(mv2 is DEFAULT_CONFIG); +} diff --git a/examples/singleton-types/singleton_types.md b/examples/singleton-types/singleton_types.md new file mode 100644 index 0000000000..d77cd24dca --- /dev/null +++ b/examples/singleton-types/singleton_types.md @@ -0,0 +1,19 @@ +# Singleton types + +A singleton type is a type that contains exactly one value. A singleton type is described using a compile-time constant expression. + +When the simple constant expression is a variable reference to a structured value, the value will be an immutable value. Therefore, a mutable value will not belong to any singleton type. + +Unions of singletons enable the definition of more refined types, constraining the value space to include exactly the allowed values, and thereby, removing the need for explicit validation. + +The type of a constant is a singleton type and a constant can be used as a singleton type. Enumerations are shorthand for unions of +string constants, and therefore, the members of an enumeration can also be used as singleton types. + +::: code singleton_type.bal ::: + +::: out singleton_type.out ::: + +## Related links +- [Constants](/learn/by-example/const-and-final/) +- [Enumerations](/learn/by-example/enumerations/) +- [Immutability](/learn/by-example/immutability/) diff --git a/examples/singleton-types/singleton_types.metatags b/examples/singleton-types/singleton_types.metatags new file mode 100644 index 0000000000..bf15e8e7a0 --- /dev/null +++ b/examples/singleton-types/singleton_types.metatags @@ -0,0 +1,2 @@ +description: This BBE demonstrates singleton types in Ballerina. +keywords: ballerina, ballerina by example, bbe, singletons, singleton types diff --git a/examples/singleton-types/singleton_types.out b/examples/singleton-types/singleton_types.out new file mode 100644 index 0000000000..7f667a40c0 --- /dev/null +++ b/examples/singleton-types/singleton_types.out @@ -0,0 +1,5 @@ +$ bal run singleton_type.bal +true +false +true +false