Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update distinct object examples #5820

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 39 additions & 11 deletions examples/distinct-object-types/distinct_object_types.bal
Original file line number Diff line number Diff line change
@@ -1,30 +1,58 @@
import ballerina/io;

// The `Person` object type that contains a string field called `name`.
type Person distinct object {
class Person {
public string name;

function init(string name) {
self.name = name;
}
};

// The `Engineer` and `Manager` classes are structurally the same but introducing the
// `distinct` keyword distinguishes them by considering them as nominal types.
distinct class Engineer {
*Person;
// The `DistinctPerson` type is a proper subtype of the `Person` type.
distinct class DistinctPerson {
public string name;

function init(string name) {
self.name = name;
}
}

// The `SomeWhatDistinctPerson` type is a subtype of the `DistinctPerson` type
// since it includes the `DistinctPerson` type's type IDs via inclusion.
class SomeWhatDistinctPerson {
*DistinctPerson;
heshanpadmasiri marked this conversation as resolved.
Show resolved Hide resolved

public string name;

function init(string name) {
self.name = name;
}
}

distinct class Manager {
*Person;
// The `EvenMoreDistinctPerson` type is a proper subtype of the `DistinctPerson`
// type since it has an additional type ID.
distinct class EvenMoreDistinctPerson {
*DistinctPerson;
heshanpadmasiri marked this conversation as resolved.
Show resolved Hide resolved

public string name;

function init(string name) {
self.name = name;
}
}

public function main() {
Person person = new Engineer("Alice");
// The `is` operator can be used to distinguish distinct subtypes.
io:println(person is Engineer ? "Engineer" : "Manager");
Person person = new ("John Smith");
io:println(person is DistinctPerson);
heshanpadmasiri marked this conversation as resolved.
Show resolved Hide resolved

DistinctPerson distinctPerson = new ("Alice Johnson");
io:println(distinctPerson is Person);

SomeWhatDistinctPerson someWhatDistinctPerson = new ("Michael Brown");
io:println(someWhatDistinctPerson is DistinctPerson);
io:println(distinctPerson is SomeWhatDistinctPerson);

EvenMoreDistinctPerson evenMoreDistinctPerson = new ("Sarah Wilson");
io:println(evenMoreDistinctPerson is DistinctPerson);
io:println(distinctPerson is EvenMoreDistinctPerson);
}
5 changes: 3 additions & 2 deletions examples/distinct-object-types/distinct_object_types.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Distinct object types
heshanpadmasiri marked this conversation as resolved.
Show resolved Hide resolved

Using the `distinct` keyword in the type definition creates distinct object types. This concept allows defining a type with nominal typing within a structured type system. This is useful when interacting with the external world through API interfaces like `GraphQL`. You may want to leverage nominal typing via this distinct typing feature of Ballerina.
For more explicit control over object type relations you can use `distinct` object types. Each distinct object type declaration has a unique type ID. When you include a distinct object type within another object type declaration, the new type's type ID set will include the type IDs of the included type. When checking if a given object type `OSub` is a subtype of a distinct object type `OSuper` there is the additional requirement that the `OSub` type must contain all the type IDs of the `OSuper` type.

Conceptually, a distinct type including another distinct type results in multiple interface inheritance.
This way you can achieve the same behavior as a nominal type system within Ballerina's structured type system, which is useful to support features such as GraphQL API interfaces.

::: code distinct_object_types.bal :::

Expand All @@ -13,3 +13,4 @@ Conceptually, a distinct type including another distinct type results in multipl
- [Error subtyping](/learn/by-example/error-subtyping/)
- [Defining classes](/learn/by-example/defining-classes/)
- [Flexibly typed](https://ballerina.io/why-ballerina/flexibly-typed/)
- [GraphQL service - Interfaces](https://ballerina.io/learn/by-example/graphql-interfaces/)
7 changes: 6 additions & 1 deletion examples/distinct-object-types/distinct_object_types.out
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
$ bal distinct_object_types.bal
Engineer
false
true
true
true
true
false
Loading