Skip to content

Conversation

@karlseguin
Copy link
Collaborator

If you look at the specification for console [1], you'll note that it's a namespace, not an interface (like most things). Furthermore, MDN lists its methods as "static".

But it's a pretty weird namespace IMO, because some of its "functions", like count can have state associated with them.

This causes some problems with our current implementation. Something like:

[1].forEach(console.log)

Fails, since this isn't our window-attached Console instance.

This commit introducing a new static_XYZ naming convention which does not have the class/Self as a receiver:

pub fn static_log(values: []JsObject, page: *Page) !void {

This turns Console into a namespace for these specific functions, while still being used normally for those functions that require state.

We could infer this behavior from the first parameter, but that seems more error prone. For now, I prefer having the explicit static_ prefix.

[1] https://console.spec.whatwg.org/#console-namespace

If you look at the specification for `console` [1], you'll note that it's a
namespace, not an interface (like most things). Furthermore, MDN lists its
methods as "static".

But it's a pretty weird namespace IMO, because some of its "functions", like
`count` can have state associated with them.

This causes some problems with our current implementation. Something like:

```
[1].forEach(console.log)
```

Fails, since `this` isn't our window-attached Console instance.

This commit introducing a new `static_XYZ` naming convention which does not
have the class/Self as a receiver:

```
pub fn static_log(values: []JsObject, page: *Page) !void {
```

This turns Console into a namespace for these specific functions, while still
being used normally for those functions that require state.

We could infer this behavior from the first parameter, but that seems more
error prone. For now, I prefer having the explicit `static_` prefix.

[1] https://console.spec.whatwg.org/#console-namespace
@sjorsdonkers
Copy link
Contributor

So the problem this is solving is that the signature of the function we were making has a this pointer as first parameter?
Is my understanding correct that this does not solve the cases where a function that requires state is passed as a function pointer to another function?
So in a next iteration we would want to be able to still pass the object to the functions, but hide it from the signature if it is static similar to *Page.

@karlseguin
Copy link
Collaborator Author

karlseguin commented Jun 3, 2025

If I understand correctly, then yes, this won't work. For example, this is valid (I'm 100% sure), but doesn't currently work (I assume, I haven't tried):

[1].forEach(console.count)

Because count requires state.

I don't think your solution would work, because we don't have the object. JS doesn't pass it to us. If we had the &window.Console, this wouldn't be an issue. In the above code, this is window (I think).

I believe the solution is that the global object (i.e. window), is supposed to be holding the state.

@sjorsdonkers
Copy link
Contributor

I believe the solution is that the global object (i.e. window), is supposed to be holding the state.

Right, and the Window already is holding that state, (all namespace like are non nullable structs) (see also performance for example)
So since the page can be passed in we already have access to the state we need, So with this we can make them all static if we want them to be static.

@karlseguin karlseguin merged commit d32fbfd into main Jun 4, 2025
11 checks passed
@karlseguin karlseguin deleted the functions branch June 4, 2025 00:33
@github-actions github-actions bot locked and limited conversation to collaborators Jun 4, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants