Skip to content

Add getters and setters (#235) - #701

Open
bvisness wants to merge 4 commits into
WebAssembly:mainfrom
bvisness:get-set
Open

Add getters and setters (#235)#701
bvisness wants to merge 4 commits into
WebAssembly:mainfrom
bvisness:get-set

Conversation

@bvisness

Copy link
Copy Markdown
Collaborator

Adds get and set to WIT and adds [get] and [set] annotations to function names, along with validation conditions.

Right now my strongly-unique rules forbid [get]foo.prop and [static]foo.prop from existing on the same resource. This seems like a reasonable and conservative choice to me. It does not forbid [get]foo.prop from existing alongside [method]foo.get-prop or [static]foo.get-prop, since we need to keep that WASI migration path open. This could be pretty easily added in the future but will make me sad because it will make the strongly-unique rules even more bonkers to implement than they already are >:(

Resolves #235.

@bvisness
bvisness requested a review from lukewagner August 17, 2026 23:04
@badeend

badeend commented Aug 18, 2026

Copy link
Copy Markdown
Member

Should this be emoji-gated?


With resource instance getters/setters spec'ed & implemented, how big do you expect the jump will be to supporting static resource getters/setters and interface-level getters/setters as well?. E.g.

interface a {
    foo: get() -> u64;
    foo: set(value: u64);

    resource r {
        bar: get() -> u64;
        bar: set(value: u64);

        baz: static get() -> u64;
        baz: static set(value: u64);
    }
}

If not too much, it might be nice to include these at the same time. Especially interface-level getters/setters already have a couple of use cases in WASI:

  • environment.get-environment
  • environment.get-arguments
  • environment.get-initial-cwd
  • monotonic-clock.get-resolution
  • system-clock.get-resolution
  • insecure-seed.get-insecure-seed
  • preopens.get-directories
  • stdin.get-stdin
  • stdout.get-stdout
  • stderr.get-stderr
  • terminal-stdin.get-terminal-stdin
  • terminal-stdout.get-terminal-stdout
  • terminal-stderr.get-terminal-stderr

@bvisness

Copy link
Copy Markdown
Collaborator Author

Should this be emoji-gated?

That seems overkill to me, since getters and setters are basically sugar with a couple extra validation rules.

how big do you expect the jump will be to supporting static resource getters/setters and interface-level getters/setters as well?

I was initially surprised by this question, but on further review, it seems like this happens in WebIDL often enough that we should probably go ahead and spec it right away. For example, Notification.permission is a static read-only property. My C-programmer sensibilities are offended, but what else is new on the web?

The same goes for interface getters with properties like CSS.highlights. This is just a thing we do, I guess.

My main concern is codegen; I would expect that many languages don't have any kind of native syntax for interface-level getters and setters in particular. A cursory LLM exploration indicates that newer versions of Python, for example, forbid you to combine @classmethod and @property, forcing you to either do something with metaclasses (🤮) or just generate a normal function with get in the name. I also instinctively dislike having too many ways to define accessors; I don't relish the idea of forever bikeshedding whether something ought to be a getter or a plain function, nor the idea of evolving getters into plain functions later when it turns out they needed a parameter.

But, if some languages have to fall back to plain old functions with get and set in the name, that's probably fine, and my other complaints are not really confined to static/interface getters in particular. Probably we can just do it, and bindings generators can just suck it up and fill in more of the matrix.

how big do you expect the jump will be to supporting static resource getters/setters and interface-level getters/setters as well?

To actually answer the question...probably not that hard. As far as validation, it's just dropping (param "self" (borrow $R)). My main question is how to compose multiple annotations together, e.g. [static][get] vs. [static,get], and also for interface getters, is it just [get]foo with no resource type?

@bvisness

Copy link
Copy Markdown
Collaborator Author

Another fun thing to consider: WebIDL's [PutForwards] allows the types of getters and setters to disagree. For example, the completely ubiquitous HTMLElement.style property is defined like so:

interface mixin ElementCSSInlineStyle {
  [SameObject, PutForwards=cssText] readonly attribute CSSStyleProperties style;
};

In other words, the setter for style forwards to style.cssText, meaning a get of style returns CSSStyleProperties, while a set of style takes string. A similar situation applies to window.location. Should we relax the restriction that the setter's value type and the getter's return type must agree? Do we have any other choice?

@lukewagner

Copy link
Copy Markdown
Member

Per our new WASI 0.3.* CM feature release process, even small additions (e.g., recently, implements) are emoji-gated and released only after a WASI SG vote (so that we are explicit about when and what can change without breaking people), so I think @badeend is right we should have an emoji-gate here.

For "static getters/setters": could we instead consider cases like Notifications.permission as being a (non-static) getter on a notifications resource whose handle is returned by a plain function on a global interface (that contains everything installed on the JS global)?

Should we relax the restriction that the setter's value type and the getter's return type must agree? Do we have any other choice?

I think this makes sense.

@bvisness

Copy link
Copy Markdown
Collaborator Author

For "static getters/setters": could we instead consider cases like Notifications.permission as being a (non-static) getter on a notifications resource whose handle is returned by a plain function on a global interface (that contains everything installed on the JS global)?

Ryan dug into this a bit and these properties don't even require a this in order to be accessed. It seems superfluous to require a handle to a resource that won't even be accessed. So honestly it does seem like I should just get over it and support static getters, although this does have name-mangling sorts of concerns.

As for the getter/setter agreement rule, I'll just go ahead and drop that. Bindings generators can just check the type agreement themselves when deciding what code to generate, and the majority of the time they should agree.

@lukewagner

Copy link
Copy Markdown
Member

Ryan dug into this a bit and these properties don't even require a this in order to be accessed.

Ah, ok. So I guess this is unlike performance.now() where, strangely, iiuc, you can't write let n = performance.now; n() b/c the receiver must actually be the Performance object.

Having to fall back to explicit get-foo/set-foo seems fine for languages that don't (and will be needed in various other cases anyways) but, just to confirm: do at least some other languages have a concept of "static" getters/setters?

@badeend

badeend commented Aug 18, 2026

Copy link
Copy Markdown
Member

do at least some other languages have a concept of "static" getters/setters?

From what I could see in #235 (comment) (see bottom of comment), the answer seems to be:
Yes, all of them.

@bvisness

Copy link
Copy Markdown
Collaborator Author

Yes, all of them.

It seems like Python might be an exception - per this page, @classmethod can no longer wrap @property as of Python 3.13. But there are probably workarounds, and it probably isn't a deal-breaker anyway.

@bvisness

Copy link
Copy Markdown
Collaborator Author

PR is updated with emoji-gating, new canonicalization rules to match #702, a rule requiring getters to precede setters for the same property, and without the rule requiring getter and setter types to agree.

I would appreciate guidance on how to specify names for static getters. How do you combine [static] and [get] into a single name?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Resource properties

3 participants