Re: [csswg-drafts] [css-mixins] Improve ergonomics of `using` by allowing wildcards (#10954)

> * We could drop `using`, treat the element variables as "global", and make them always available in all functions (shadowed by locals, obviously).
> * Or, we could make `using` apply to the the element variables only. Passing values from one function to the next would then happen in a civilized manner, i.e. with regular parameters only.

Both of these mean that functions can have arguments that *one* calling context is allowed to control (the element itself), but all other contexts can't. If you write a function that calls other functions, the "global" variables they're grabbing simply bypass you entirely.

Neither of them fix the "dynamic scoping" aspect of the concept, they just make that scoping *even less controllable*. I'm not sure why we'd want that.

The point of `using` is to allow theming variables to be passed into a function without having to explicitly list every single one of them in every single function definition *and* every single call site. In fuller programming languages, all these variables would probably be bound into a single wrapper object for easy passing, or globally referenced but locally redirectable. That latter behavior is basically what I'm trying to achieve with my `using` behavior suggestion.

Like, check out [my Bikeshed usage of `with m.withMessageState()`](https://github.com/speced/bikeshed/blob/main/bikeshed/test.py#L111) and [the corresponding definition of  `withMessageState()`](https://github.com/speced/bikeshed/blob/main/bikeshed/messages.py#L291) - the printing functions all reference the global `MessageState` object for their config by default, but by using `with m.withMessageState()`, I can override their config *for all printing within this call stack*. This isn't a particular unusual pattern, and it's very useful. CSS, tho, is too weak of a programming language to actually implement this *natively*, but we can reproduce the *functionality* for a specific use-case, and "reference 100+ theming variables initially set at the root" is exactly the use-case that needs this.

Looked at another way, this is just carrying the custom property inheritance behavior from elements into functions. We already recognize that being able to override a custom property on an entire subtree by changing it on the common ancestor is useful; it would be *quite bad* if *every single element* in the subtree had to manually indicate it was inheriting all the custom properties its descendants were using.

-------

The point of adding `using` was just to make it clearer to authors of functions what variables were available to them, and users of functions what variables are *used* by the function (without having to inspect the entire body). We could remove it and just instead make all the locally-visible variables at the call site available (so, overridden by function arguments or custom props inside the function body), so it's *exactly* like custom property inheritance in the tree. I just thought that would be somewhat less good. But I'm not *opposed* to it, if that's preferred.

I *am* opposed to (a) not exposing element variables at all, so arg lists have to be enormous and coordinated, or (b) exposing specifically *element* variables, in a way that can't be overridden at the call site, as it means inlining a function can change its behavior. Maintaining beta reduction is important, I think.

-- 
GitHub Notification of comment by tabatkins
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/10954#issuecomment-2389799946 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Wednesday, 2 October 2024 22:33:02 UTC