wing icon indicating copy to clipboard operation
wing copied to clipboard

Support getters in interfaces

Open eladb opened this issue 2 years ago • 12 comments

Feature Spec

Wing interfaces now support fields.

interface IMyInterface {
  get mynumber(): num;
  get mystery(): str;
  method(): void;
}

For now, let’s only support get properties.

When an interface is implemented by a class, properties can be implemented using fields:

class MyClass impl IMyInterface {
  mynumber: num;
  mystery: str;
  // ...
}

In the future we will support defining properties on classes as well and then they can also be used as an implementation of getters in interfaces.

Use Cases

API design tools

Implementation Notes

No response

Component

Compiler

Community Notes

  • Please vote by adding a 👍 reaction to the issue to help us prioritize.
  • If you are interested to work on this issue, please leave a comment.
  • If this issue is labeled needs-discussion, it means the spec has not been finalized yet. Please reach out on the #dev channel in the Wing Slack.

eladb avatar Nov 16 '23 08:11 eladb

+1 @eladb I remember that you were initially against this, I'm curious what changed your mind.


In addition to this change, I think we should evaluate the purpose of structs. In terms of type expressiveness, this change makes structs a subset of interfaces. structs no longer serve a purpose that can't be solved by the compiler itself. Why not get rid of structs and support interfaces everywhere structs are used i.e.:

// maybe we stop calling them interfaces and call them `type` or `shape` instead
interface Whatever {
  field: num;
  func(): void;
}

let x = Whatever {
  field: 2,
  func() {}, // or `func: () => {},` I guess
}

If the concern is "structs are special because they provide a guarantee of no functions/behavior", I would say:

  1. We're statically typed, the compiler knows if interfaces do/don't have functions
  2. This isn't even true to begin with, as structs can have class instances as fields

MarkMcCulloh avatar Nov 16 '23 16:11 MarkMcCulloh

I remember that you were initially against this.

mmmm. not sure I recall to be honest. i don't have any problem with it.

In addition to this change, I think we should evaluate the purpose of structs

there's a fundamental difference between behavioral interfaces and data structures in my mind. i don't think structs and interfaces are the same thing. for example, Struct.fromJson doesn't make any sense on interfaces.

happy to discuss more, but probably not over this issue...

eladb avatar Nov 17 '23 12:11 eladb

@eladb, @Chriscbr , @MarkMcCulloh - do you know if JSII supports interface fields?

staycoolcall911 avatar Nov 20 '23 12:11 staycoolcall911

yes, it is supported.

eladb avatar Nov 20 '23 16:11 eladb

Option 1:

interface IFoo {
  field1: str;
}

class Foo impl IFoo {
  pub x: str;
}

Option 2:

interface IFoo {
  get field1: str;
}

class Foo impl IFoo {
  pub x: str;
}

eladb avatar Nov 30 '23 15:11 eladb

I like the idea of some syntax for specifying if the field is set-able or not, it could be a useful API design tool.

Chriscbr avatar Nov 30 '23 18:11 Chriscbr

Should we use the typescript notation get x(): str or get x: str?

What would be the syntax for setters?

get set foo: str;

or:

get foo(): str;
set foo(x: str): void;

eladb avatar Dec 03 '23 14:12 eladb

For inspiration, here's how Swift approaches it https://docs.swift.org/swift-book/documentation/the-swift-programming-language/protocols#Property-Requirements

Of the two options you mentioned @eladb I like the first one better since I don't have to type the field name twice.

How does a user add computed properties to a class?

Chriscbr avatar Dec 03 '23 18:12 Chriscbr

How does a user add computed properties to a class?

Maybe like in TypeScript:

class MyClass {
  get value(): num {
    return 12;
  }

  set value(v: num) {
    log("setting value to {v}");
  }

But there's something a bit weird about the difference between declarations in interfaces and definitions in classes, no?

eladb avatar Dec 05 '23 13:12 eladb

Let's avoid bike shedding and just go with the typescript syntax for now. I think it's pretty solid.

Updated summary.

eladb avatar Dec 05 '23 21:12 eladb

Hi,

This issue hasn't seen activity in 60 days. Therefore, we are marking this issue as stale for now. It will be closed after 7 days. Feel free to re-open this issue when there's an update or relevant information to be added. Thanks!

github-actions[bot] avatar Feb 09 '24 06:02 github-actions[bot]

I think I ran into this issue while trying to implement https://github.com/winglang/wing/issues/6412. I exposed an inflight interface in the SDK for an AWS Lambda Context Object in the SDK (see ILambdaContext in https://github.com/winglang/wing/pull/6424/commits/e9fe25142f1e0301549a04484672edadd10f0151), but the compiler panics with a message "No support for inflight properties yet" when type checking it. I think I might be able to work around this case by making them methods and adding some more wrapper code, but support for inflight properties would make a big difference here.

Chriscbr avatar May 06 '24 22:05 Chriscbr