From d644a887cf24bff2e0de7a80034423ab0bb46a3f 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/index.json | 7 ++ 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 ++ 5 files changed, 97 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/index.json b/examples/index.json index aca32d26d7..ab36f87732 100644 --- a/examples/index.json +++ b/examples/index.json @@ -421,6 +421,13 @@ "verifyOutput": true, "isLearnByExample": true }, + { + "name": "Singleton types", + "url": "singleton-types", + "verifyBuild": true, + "verifyOutput": true, + "isLearnByExample": true + }, { "name": "Stream type", "url": "stream-type", 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..b3bf7ac73d --- /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_types.bal ::: + +::: out singleton_types.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..afeb041954 --- /dev/null +++ b/examples/singleton-types/singleton_types.out @@ -0,0 +1,5 @@ +$ bal run singleton_types.bal +true +false +true +false