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

Allow service types to have methods that do not have to be implemented #1320

Open
jclark opened this issue Nov 1, 2024 · 6 comments
Open
Assignees
Labels
Area/Lang Relates to the Ballerina language specification design/usability Design does not work well for some tasks Type/Improvement Enhancement to language design

Comments

@jclark
Copy link
Collaborator

jclark commented Nov 1, 2024

A service declaration allows a type-descriptor to be specified for the type of the constructed service object. When declaring a service for an async API, it would be natural to use this to refer to a service type describing the async API, so that the compiler can check that the declared service is consistent with the async API.

This is not useful at the moment because a service object has to provide an implementation of every method declared in the service type, but often an implementation only needs to implement a few of these methods.

This contrasts with the situation with record types and mapping constructors: a mapping constructor does not to have to specify values for those fields that the record type declares as optional or provides a default for.

@jclark jclark added the design/usability Design does not work well for some tasks label Nov 1, 2024
@jclark jclark self-assigned this Nov 1, 2024
@jclark
Copy link
Collaborator Author

jclark commented Nov 1, 2024

One possible solution to this is to allow service object types to declare remote methods as optional. The natural syntax is to use a ? after the method name ((TypeScript uses a similar syntax) e.g.

remote function onError?(string msg);

The semantics are as expected: a service object can belong to the service type even if it does not define a remote method onError. But if it does define this method, the type of the method must be the same requirements as if the service type remote method was not optional.

@jclark
Copy link
Collaborator Author

jclark commented Nov 1, 2024

There's one significant problem. The user might make a mistake in the name of the method, for example they might declare the method as onErr rather than onError. Since the onError method is optional and since object types are always open (in the sense that additional methods are always allowed), this would not be an error.

There is a similar problem with optional fields in records. The way that Ballerina solves this is to require the field name to be specified as a literal string rather than an identifier in certain cases: specifically, when the inherent type is an optional record type with specific fields, but the mapping constructor is specifying an field name that is not in the record type, then you have to specify the name of the field as a literal string.

One could do something similar by saying requiring the use of quoted method names for remote methods not in the service type, when the service type includes optional remote methods. In this case, to bring consistency between method names and fields names, one could extend the handling of record field names to treated quoted identifiers similarly to literals, or one could allow remote method names to be specified as strings. I don't feel very enthusiastic about this solution, though.

In this case, I think I would prefer to rely on an annotation on the service type to say that this type is being used in an exhaustive way, and it doesn't make sense for the service declaration to define remote methods not in the service type. (Or could this be an annotation on listener types that are intended for async use?)

@jclark jclark added the Type/Improvement Enhancement to language design label Nov 1, 2024
@jclark
Copy link
Collaborator Author

jclark commented Nov 1, 2024

It would also be possible to extend this to allow objects to have optional methods generally. But in this case we would need a syntax to call optional methods. The natural thing would be to extend the existing ?. syntax to do method calls.

We would also need a more general solution to the problem in the previous comment.

@hasithaa
Copy link
Contributor

hasithaa commented Nov 1, 2024

To address the problem you described in the comment, we can enforce the users to define function signature without the block statement if it is optional. If the block statement is present, the function is implemented. This approach is explicit and readable in the source code and the diagram editor.

When we call an optional method, I think it should return (). So ?.method() like syntax works.

type Foo object {
    function bar?(string a, int b) returns int;
}

class FooImpl {

    *Foo;
    function bar(string a, int b) returns int ;
}

class FooImpl2 {

    *Foo;
    function bar(string a, int b) returns int { 
         return 1;
    }
}

public function main() {
    FooImpl foo1 = new;
    int? res1 = foo1?.bar();
    
    FooImpl2 foo2 = new;
    int? res2 = foo2?.bar(); 
}

Another alternative is to use = external; like syntax to indicate the method is optional.

@jclark
Copy link
Collaborator Author

jclark commented Nov 2, 2024

I agree optional method call would return () when the method does not exist.

type Foo object {
    function bar?(string a, int b) returns int;
}

class FooImpl {

    *Foo;
    function bar(string a, int b) returns int ;
}

Are you suggesting that this would mean that FooImpl does not have a bar method?

@hasithaa
Copy link
Contributor

hasithaa commented Nov 2, 2024

It suggests that there is no implementation of the bar method in the Foolmpl. It does not exactly give the meaning of optional. But, type-checking is straightforward. And it solves the problem of not defining the method signature, such as typos.

@anupama-pathirage anupama-pathirage added the Area/Lang Relates to the Ballerina language specification label Nov 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area/Lang Relates to the Ballerina language specification design/usability Design does not work well for some tasks Type/Improvement Enhancement to language design
Projects
None yet
Development

No branches or pull requests

3 participants