| 15:16 | <bakkot> | my takeaway from this poll is not "we need a bunch more syntax for accessors" |
| 15:18 | <nicolo-ribaudo> | Oh damn I missed the beginning of plenary, thank you for writing a message here |
| 15:20 | <nicolo-ribaudo> | Is there a link to the slides? |
| 15:20 | <Aki> | reminder to note-takers that if the captioner is inserting newlines, they don't have to worry about those. I'll take care of them at conversion time. |
| 15:22 | <Chris de Almeida> | proposal repo, it's html |
| 15:22 | <Chris de Almeida> | https://github.com/LeaVerou/proposal-composable-accessors |
| 15:22 | <Chris de Almeida> | slides dir |
| 15:22 | <nicolo-ribaudo> | Thank you |
| 15:25 | <bakkot> | I am confused about what this "internal property" is that is not the existing accessor property |
| 15:27 | <nicolo-ribaudo> | Maybe this proposal is pointing to a need to split off accessor from the decorators proposal so that it's not blocked on them? |
| 15:28 | <rbuckton> | accessor is sort of split off. It was originally introduced in Grouped and Auto-Accessors and brought over to decorators to meet implementor requirements |
| 15:31 | <nicolo-ribaudo> | I think I would prefer for these things to be reified as accessors and not directly visible in descriptors, to avoid making descriptors being more complex |
| 15:54 | <nicolo-ribaudo> | What's the time box? I noticed we are almost at the hour, and my reply is low priority so I can drop it if needed |
| 15:54 | <bakkot> | 1 hour |
| 15:59 | <keith_miller> | nicolo-ribaudo: Which syntax were you talking about the one on the slide now with the decorator? |
| 15:59 | <nicolo-ribaudo> | The one with the validate keyword |
| 16:00 | <keith_miller> | Or the class Foo { accessor x = 2; } syntax? |
| 16:00 | <nicolo-ribaudo> | I meant that class Foo { validate x(val) { ... } } looks a lot like class Foo { set x(val) { ... } }, so I'd expect similar performance |
| 16:01 | <nicolo-ribaudo> | I'd also expect similar perf with the decorator example, since I'm literally seeing a function attached to the property |
| 16:01 | <nicolo-ribaudo> | I would have less of that expectaton for a plain accessor x = 2, but I guess most times you'd want to decorate that anyway |
| 16:02 | <nicolo-ribaudo> | I wonder if accessor x = 2 is more optimizable though, since there is no user code running there even if it's a get/set pair |
| 16:02 | <keith_miller> | The motivation for this, as I understand it anyway, is to use it everywhere for reflection/metaprogramming |
| 16:03 | <keith_miller> | Which is the reason I mentioned hiding the cost of the call. Not sure about others |
| 16:04 | <nicolo-ribaudo> | Ok I think I was mostly focusing on the second use case, I'm not sure I agree with the first one |
| 16:04 | <ljharb> | only for the use cases where the instance shape is needed from outside |
| 16:04 | <nicolo-ribaudo> | For this could we have a bult-in @public decorator, with the decorators metadata proposal? |
| 16:04 | <nicolo-ribaudo> | That marks it as "public" in the metadata |
| 16:06 | <ljharb> | true - and a class decorator could do it all in one |
| 16:06 | <keith_miller> | Are people realistically going to add the mental overhead of figuring that out though? My assumption would be that codebases that don't particularly care about performance would just apply it everywhere |
| 16:07 | <ljharb> | sure but if they don’t care about performance then it doesn’t matter there, right? |
| 16:07 | <bakkot> | we care about performance even if they don't |
| 16:08 | <nicolo-ribaudo> | "people are not thinking about what things make their code slow" and "people want their code to be fast" unfortunately have a large intersection |
| 16:08 | <bakkot> | we should design the language such that even people who don't care about performance end up on the happy (= reasonably performant) path |
| 16:09 | <ljharb> | fair |
| 16:20 | <rbuckton> | New features aren't necessarily free, especially when we implement whole new capabilities to the language. |
| 16:27 | <nicolo-ribaudo> | I'm looking at my accessors usage, and they are (numbers are not measured):
|
| 16:27 | <nicolo-ribaudo> | The % symbol obviously means " / 105" |
| 16:27 | <rbuckton> | For point 1 in the problem statement, would we ever consider adding something like Function.getInstanceFieldNames(ctor)? |
| 16:28 | <nicolo-ribaudo> | Some feedback that was shared at last plenary is that class fields should behave similarly to properties defined in the constructor |
| 16:28 | <rbuckton> | You could add a proxy trap for it like apply/construct |
| 16:29 | <rbuckton> | I don't necessarily agree with that position, though I do agree you shouldn't be able to just grab them via getOwnPropertyDescriptors. |
| 16:30 | <rbuckton> | A getInstanceFieldNames would be simpler than a @Public decorator that uses Symbol.metadata to do the same thing |
| 16:34 | <waldemar> | Test message; please ignore |
| 16:36 | <waldemar> | (Matrix seems to have glitched and kicked me out for a while) |
| 16:44 | <rbuckton> | If Decorators were at stage 4, the composable accessors piece would easily be a public API proposal a la iterator helpers or similar, which would likely be easier to discuss and advance |
| 16:48 | <rbuckton> | That said, most of the composition pieces presented or in the explainer could be implemented in userland decorators first before standardizing |
| 16:49 | <rbuckton> | The built-in decorators that can't be implemented in userland that I'm mostly interested in are not these composable decorators, however. |
| 16:57 | <nicolo-ribaudo> | Let's continue with this please, to keep context |
| 17:02 | <Michael Ficarra> | overall the transcription was pretty good but there was a writer switchover at 11:00 while @rbuckton was speaking and that paragraph got completely mangled |
| 17:02 | <Michael Ficarra> | you'll know it when you see it |
| 17:02 | <Michael Ficarra> | @rbuckton do your best to fix it up |
| 17:05 | <hax (HE Shi-Jun)> | Yeah I have similar usage, and I think lazy init is especially hard to expresss even with current decorator proposal. |
| 17:16 | <hax (HE Shi-Jun)> | But if u consider validate/sideeffect use cases, it actually don't require to be use accessor but only some observer ability. Force it to become accessor have performance result (To be clear, I don't care much about perf issue, but I always hear some delegates attack some proposals use this reason). |
| 17:18 | <hax (HE Shi-Jun)> | I think lea already suggest similar proposal in last meeting and be refused? Or maybe I misunderstand it? |
| 17:20 | <Lea Verou> | Oooh yes, lazy init is another big one. |
| 17:21 | <Lea Verou> | While most things can be done with decorators, I suspect alias accessors likely would need some syntax if we want to support private members. And property chains would be a lot more elegant as an actual language construct (like in delete) as opposed to e.g. an array of property names. |
| 17:21 | <hax (HE Shi-Jun)> | To be honest, my question is, whether decorator could really go to stage 4, considering the position of browser vendors? (If there was any news on that, pls tell me...) |
| 17:23 | <Lea Verou> | Another advantage of the decorators direction is that it's a lower-cost way to prototype and test the waters. E.g. if this ends up being used tremendously much, we could introduce a syntax-level solution down the line. For this alone, I'm actually now myself in favor of the decorators direction |
| 17:23 | <hax (HE Shi-Jun)> | @lazy accessor x = lazy.of(() => init) // example provided by Jack WorksFull of syntax noise 🙃 |
| 17:25 | <rbuckton> | Which paragraph? |
| 17:25 | <Lea Verou> | hax (HE Shi-Jun): it doesn't need to, it could be let { lazy } = SomeObject and then just @lazy(init) accessor x . I'm less worried about O(1) DX issues, it's the O(N) (per property) DX issues that are the main problem |
| 17:28 | <hax (HE Shi-Jun)> | I'm afraid @lazy(init) does not work if u want to access something on the instance in initializer? |
| 17:31 | <nicolo-ribaudo> | @lazy accessor x = () => init? |
| 17:36 | <hax (HE Shi-Jun)> | I think u can't make it type safe in ts. Though it maybe the fault of TS 😆 |
| 17:38 | <hax (HE Shi-Jun)> | Anyway, I really feel lazy init is too common and should have better DX. If u check other morden langauge, in Kotlin u write var x by lazy { ... }, in swift u write lazy var x = { ... }(), in Scala u write lazy val x = { ... }. It's shame that we can't provide js programmers a good solution |
| 17:38 | <ljharb> | A |
| 17:39 | <Lea Verou> | hax (HE Shi-Jun): A way I often implement lazy accessors myself is to set a symbol property in the getter and just return that if set. I believe that can totally be done with decorators, right? |
| 17:39 | <Steve Hicks> | That's my point about well-known builtin decorators - TypeScript could learn the type calculus behind them. |
| 17:44 | <hax (HE Shi-Jun)> | Obviously 10 js developers can have 10 different way to do it. If u ask GPT it may teach u write class C { get val() { Object.defineProperty(this, 'val', { value: expensive(), writable: false }); return this.val; } } |
| 17:45 | <Lea Verou> | Yes, but if it's a built-in decorator that's not an issue |
| 17:46 | <hax (HE Shi-Jun)> | I'm very curious how engine vendors see such re-defining prop descriptor which LLM like to encourage but they refused in decorator proposal. |
| 17:52 | <hax (HE Shi-Jun)> | Is there any specific reason that it should be opt in? And what opt-in mechnism will u like to see? |
| 18:00 | <Jack Works> |
|
| 18:01 | <rbuckton> | It's certainly feasible for TS to implement. It's on the backlog and I had planned to work on it at some point. |
| 18:02 | <nicolo-ribaudo> | Put those that didn't help yet during this meeting on random.org/lists and pick two! |
| 18:03 | <Aki> | yoooo it's Julie captioning |
| 18:03 | <Aki> | she's really good |
| 18:05 | <Andreu Botella> | we should do this every time – maybe excluding first-timers |
| 18:06 | <ljharb> | because anything that's introspectable is part of the public API and a breaking change if altered. i don't care what the mechanism is, it just has to be solely up to the class author. separately, public class fields are sugar for statements in the constructor, and statements inside function bodies are never introspectable in the language, nor should they be. |
| 18:06 | <Aki> | the only reason the chairs haven't done that in the past (at https://takingnotes.rocks) is that there are some people who can't for personal reasons and it's not fair to put them on the spot |
| 18:07 | <rbuckton> | Isn't that why we have private fields? public fields are introspectable on an instance, just not from a constructor. IMO, you shouldn't need to construct an instance for that introspection. |
| 18:07 | <nicolo-ribaudo> | I mean the chairs could do the extraction privately, and those people can privately ask them in advance to be excluded |
| 18:08 | <ljharb> | nope, they're not. public properties on the resulting instance are, certainly. but the existence of a field does not guarantee it will end up as a property, nor will the list of fields be exhaustive (meaning there could eventually be properties not in that list). (remember any subclass can arbitrarily delete a property that a field created, for example) |
| 18:10 | <rbuckton> | A field declaration will definitely guarantee its presence as a data property. They are always installed on an instance (barring use of delete, which is rarely a good idea). |
| 18:11 | <ljharb> | ok but the existence of that caveat means that it's not a guarantee. |
| 18:11 | <hax (HE Shi-Jun)> | But u already can use Object.getOwnPropertyNames() or other api or syntax to get the own properties... I don't see any difference here (except u can only get them via object not class). |
| 18:11 | <ljharb> | of the instance. you can't do that from a constructor alone. |
| 18:11 | <ljharb> | nor should you be able to, without the permission of the class author. |
| 18:11 | <rbuckton> | You can delete methods and accessors as well |
| 18:11 | <ljharb> | indeed you can |
| 18:12 | <ljharb> | but that you can introspect on the class. |
| 18:12 | <ljharb> | overall, implicit reflection/introspection is a horrifically bad language "feature" and we should go out of our way to not introduce any additional cases of it. |
| 18:12 | <ljharb> | explicit/opt-in reflection is great though! i fully support an author's freedom to expose what they want. but it must be a choice. (ideally it's an easy one, just explicit) |
| 18:13 | <rbuckton> | I strongly disagree with that sentiment. |
| 18:13 | <ljharb> | that is unsurprising :-) |
| 18:13 | <ljharb> | but suffice to say there's no consensus to add any new implicit/default introspection mechanisms, though. |
| 18:14 | <rbuckton> | IMO, it's a terrible idea to use delete on any member of a class. |
| 18:14 | <ljharb> | oh i agree |
| 18:14 | <ljharb> | lots of things in any language are a terrible idea. but they still exist. |
| 18:14 | <rbuckton> | And you certainly won't be able to delete fields from struct instances. |
| 18:15 | <ljharb> | which is great |
| 18:15 | <hax (HE Shi-Jun)> | ljharb: " public class fields are sugar for statements in the constructor, and ..." --- No they are not sugar. No one write "Object.defineOwnProperty(this, "name", ...) in constructor. 😂 |
| 18:15 | <ljharb> | that nobody writes it is why it's sugar |
| 18:15 | <ljharb> | and prior to the [[Define]] decision it was sugar for the thing everyone writes, which is this.foo = 'bar' |
| 18:17 | <hax (HE Shi-Jun)> | Ok. I mean, no one want to [[Define]] before this feature, so it's really weird to me to see it as sugar. I always see sugar should not introduce uncommon semantic. |
| 18:18 | <nicolo-ribaudo> | Oh well I can't speak sorry. It's for Trusted Types, it is being implemented |
| 18:19 | <nicolo-ribaudo> | It's not ready for stage 4 yet though, according to my colleague working on it |
| 18:21 | <hax (HE Shi-Jun)> | ljharb: On the other side, why it should be opt-in but not opt-out?? For example, in TS you use private x which seems match the case you want (by default it's public api, but private means it's not public) |
| 18:26 | <keith_miller> | Can uhh, I convince one of the chairs to add the 3.md agenda so I can add Atomics.pause to stage 4 before I forget... :) |
| 18:26 | <hax (HE Shi-Jun)> | ljharb: To be clear, I think opt-in is ok, I even like everything is not public by default, but JS class already make methods public, it's really weird that only fields need to opt-in for public. |
| 18:29 | <ljharb> | TS's private is bad for a ton of reasons so i don't think it should be used as an argument |
| 18:30 | <ljharb> | because a "field" isn't a first-class thing. a field is just instructions to set up a property - which is indeed public by default. iow, it's sugar. |
| 18:30 | <ljharb> | yes, i will do that now |
| 18:34 | <Zb Tenerowicz (ZTZ/naugtur)> | I might be interested in co-championing @ljharb:matrix.org: but will need a comprehensive intro |
| 18:39 | <hax (HE Shi-Jun)> | I am not sure what "first-class" means. In my opinion, the whole point of fields proposal is to make it declarative and get the "first-class" support in the language. |
| 18:43 | <Olivier Flückiger> | @erights Mark Miller (Agoric) MM: I have a counter for last match, left context and right context. It is surprisingly not that small: https://chromestatus.com/metrics/feature/timeline/popularity/5641#V8RegExpStaticPropertiesWithLastMatch |
| 18:44 | <Olivier Flückiger> | We would also have counters for the rest (and most probably more common) of the static regexp properties, but it seems there is a feature id collision so that counter is broken... |
| 18:45 | <ljharb> | it means "a thing you can pass around". variables are not first-class; objects are, for example. |
| 18:45 | <ljharb> | things that aren't first-class aren't reified "things" |
| 18:45 | <ljharb> | k, now done |
| 18:48 | <hax (HE Shi-Jun)> | So why some class members (methods and accessors) are first-class, others (fields) are not? very inconsistent. |
| 18:48 | <nicolo-ribaudo> | Interesting, I can see usage of .lastMatch/leftContext/rightContext on the xiaomi website but not in the other two of the top 3 |
| 18:49 | <ljharb> | that's not a consistency that i'd expect anyone to expect, but sure, it's inconsistent. the "why" doesn't change that it's the way it is. classes are declarative - they're instructions. that some pieces of them turn into first-class things and some don't is just based on the semantic of the instructions. static blocks aren't first-class either, and neither are private fields. |
| 18:51 | <nicolo-ribaudo> | And the fourth one is coming from a twitter sdk (https://github.com/twitter/twitter-text): https://github.com/twitter/twitter-text/blob/30e2430d90cff3b46393ea54caf511441983c260/js/src/extractUrlsWithIndices.js#L70 |
| 18:54 | <nicolo-ribaudo> | Which is unmaintained but has 50k downloads/week |
| 18:58 | <rbuckton> | I'm back, sorry for the interruption |
| 19:00 | <Olivier Flückiger> | I found that the combined counter is probably correctly working: https://webstatus.dev/features/regexp-static-properties?q=RegExp . 7% :(( |
| 19:01 | <nicolo-ribaudo> | Unfortunately not only that library has no recent activity, but every single person that worked on it seems to not be working at that company anymore |
| 19:02 | <rbuckton> | Built-in decorators (+ function decorators) would allow something like C#'s StackTraceHiddenAttribute https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.stacktracehiddenattribute?view=net-10.0 |
| 19:05 | <Olivier Flückiger> | Yeah, but I think the fact that the other static properties are used even more is worse. Unless we split the proposal to only remove the little used ones. |
| 19:05 | <ljharb> | I have to drop, tty all next time |
| 19:06 | <nicolo-ribaudo> | Looking at that file, we can work on a proposal to remove RegExp.$6! 😛 |
| 19:09 | <hax (HE Shi-Jun)> | Have no idea why xiaomi website use such legacy feature, I will try to find and ask the guys in xiaomi 🤨 |
| 19:09 | <Michael Ficarra> | thank you for hosting this session Peter! |
| 19:10 | <Steve Hicks> | I'm a Matrix n00b, is there a place where these different spaces are listed? |
| 19:11 | <Chris de Almeida> | if only there were...some kind of guide... like a matrix guide.. with information on matrix |
| 19:11 | <Chris de Almeida> | https://github.com/tc39/how-we-work/blob/main/matrix-guide.md |
| 19:11 | <Chris de Almeida> | https://matrix.to/#/#tc39-space:matrix.org |
| 19:12 | <Chris de Almeida> | ☝️ TC39 space |
| 19:22 | <peetk> | what was this in response to? isTemplateObject? |
| 19:26 | <peetk> | my pleasure! |
| 19:26 | <rbuckton> | For simple field wrapping to support public read/private write, I'd argue for this feature proposed in grouped accessors:
For more complex cases (like subproperty access), |
| 19:35 | <rbuckton> | I have been tempted to propose something like C#'s "expression bodied methods", which use
Which could could cut down on boilerplate for the
|
| 19:35 | <keith_miller> | nicolo-ribaudo: How many lines of code did your numbers come from BTW? |
| 19:38 | <Zb Tenerowicz (ZTZ/naugtur)> | Yes |
| 19:38 | <nicolo-ribaudo> | Around 200k in a few repos, but I didn't measure as I said above. I scrolled through search results and eyeballed it. |
| 19:38 | <nicolo-ribaudo> | All property forwarding was about getters btw, setters are much rarer |
| 19:39 | <nicolo-ribaudo> | One codebase uses typescript, the others do not. Validation is higher in the ones that do not use TS |
| 19:41 | <Zb Tenerowicz (ZTZ/naugtur)> | I have some appreciation for the feature and have been looking at ASTs of tagged templates recently |
| 19:44 | <rbuckton> | This seems like a good use case for expression-bodied getters, IMO. i.e., get x => this.#x |
| 19:46 | <Lea Verou> | is there a proposal for this? (edit: nvm, just saw the earlier messages!) |
| 19:48 | <Steve Hicks> | Couldn't aliases/forwarding be done with a decorated accessor? It would be a little wasteful of the unused underlying accessor, but there's any number of ways you could write
or
And if you wanted to define a bunch of them, you could compose your own decorator that saved some boilerplate
where |
| 19:48 | <rbuckton> | Not yet. I'd considered it when I proposed grouped/auto-accessors but since that proposal was blocked from Stage 2 until decorators hit Stage 4, I held off. |
| 19:49 | <Lea Verou> | Separating the object from the prop like that seems even more awkward than the status quo |
| 19:49 | <Lea Verou> | though this makes me wonder if instead of alias accessors we need a syntax-level feature for referencing property chains |
| 19:49 | <rbuckton> | that certainly isn't very concise, imo. |
| 19:49 | <Lea Verou> | then regular decorators could do it |
| 19:49 | <Lea Verou> | plus, lots of other use cases outside accessors |
| 19:50 | <rbuckton> | C# has Expression<T> that's used in LINQ, but that requires reifying a subset of the AST |
| 19:50 | <Lea Verou> | E.g. filtering, various helpers (e.g. lodash's get/set) |
| 19:51 | <rbuckton> | Well, not quite the same. Expression<T> is used by an expression rewriter to turn C# expression syntax into other languages like SQL to convert a LINQ pattern into a database query. |
| 19:52 | <Lea Verou> | basically a type of literal that returns some kind of PropertyReference object |
| 19:53 | <Lea Verou> | which could have methods to get/set/etc the property chain for a given object, perhaps (Just brainstorming out loud here) |
| 19:53 | <rbuckton> | I have a proposal for reified references that I have yet to bring to committee (https://github.com/rbuckton/proposal-refs) that would do that. |
| 19:54 | <Lea Verou> | Thanks! I'll need to look at this more closely later, I tried skimming but it needs more time than that |
| 19:55 | <Lea Verou> | It could be useful to include examples of property chains and privates (if it covers them too) |
| 19:57 | <rbuckton> | It does. |
| 19:58 | <rbuckton> | Though "property chain" isn't the right term. It captures the Reference resulting from the property chain. |
| 19:58 | <Steve Hicks> | FWIW (probably not much), my Closure Compile-addled brain tends to go to something along the lines of {foo: {bar: true}} to represent a property chain... but that's more due to limitations with how our optimizer handles property renaming. I don't know if {#foo: {bar: true}} could work (assuming privates in object literals landed), but it's certainly neither pretty nor performant and probably a non-starter. |
| 20:02 | <Steve Hicks> | But at the end of the day, what we're talking about is a pair of functions: {get: (T) => V, set: (T, V) => void}, so I think the question is whether there could be a reasonably ergonomic way to write that object. |
| 20:05 | <rbuckton> | The idea with
While a
|
| 20:07 | <rbuckton> | There's no concept of a ref declaration for a field or accessor however, so while you could take a ref to a property, you can't necessarily install the ref as a property (at least, not yet) |
| 20:13 | <rbuckton> | There is a suggestion for ref properties, though (https://github.com/rbuckton/proposal-refs/issues/12) |
| 20:13 | <rbuckton> | I really should just present this and at least get stage 1, since one way or another it's worth discussing. |
| 20:18 | <Lea Verou> | That seems to be the desirable behavior? Are there any cases where that would break expectation? |
| 20:19 | <Lea Verou> | Oof, that's quite a problem. Do you think it's fixable? |
| 20:19 | <rbuckton> | Yes, I'm just saying "property chain" is the wrong terminology. to me, "property chain" implies that if some part of the chain is replaced, re-evaluating would produce a different result. |
| 20:20 | <rbuckton> | See https://github.com/rbuckton/proposal-refs/issues/12 |
| 20:21 | <Lea Verou> | For that to work for the intended use cases, it basically needs to re-evaluate the chain itself, kind of like a very very limited eval almost. Which seems like the case here? (aside from the issue above) |
| 20:25 | <rbuckton> | For the intended use case, only the Reference at the end matters. Consider:
the intermediates don't matter, only the trailing Reference |
| 20:25 | <hax (HE Shi-Jun)> | Yeah, I’ve always liked the refs proposal. Just one thing I’m a bit concerned about is the syntax Maybe a syntax like |
| 20:26 | <rbuckton> | ref is a placeholder. It could easily be &. I just was veering away from C-like addresses and pointers. |
| 20:27 | <rbuckton> | However, ref x.y.z works with a Reference the same way delete x.y.z does and is consistent with JS on the whole. |
| 20:27 | <rbuckton> | x.&r looks highly confusing to me |
| 20:28 | <rbuckton> | ref (as expression and as declaration) also has prior art in C# |
| 20:28 | <hax (HE Shi-Jun)> | ah, I forgot delete x.y.z, I suppose no one use delete in most morden JS/TS 😂 |
| 20:29 | <rbuckton> | I would not want & or ref to come in the middle of a property access. It could get lost in a deeply nested chain. |
| 20:29 | <Lea Verou> | For alias accessors, the entire chain matters. E.g. suppose I have
If I replace |
| 20:29 | <Lea Verou> | Also, there are use cases that need access to the intermediate properties (e.g. lodash's get/set that I mentioned earlier) |
| 20:29 | <rbuckton> | If that's the case, then ref is not what you want. But I also wouldn't use = as that implies an immediate assignment |
| 20:30 | <Lea Verou> | Yes, that exact issue was an open question in the explainer (that = is probably not appropriate) |
| 20:30 | <rbuckton> | You could just as easily use as or for or ->, etc. |
| 20:30 | <Lea Verou> | But also, after this discussion I'm starting to think that this should also be done with decorators, and we should instead introduce a syntax primitive to make it nice (even if it's not ref) |
| 20:31 | <Lea Verou> | There was another proposal in the previous meeting that also needed a way to reference property chains, I forget which one, and there was no good story (perhaps the deep diffing one?) |
| 20:31 | <hax (HE Shi-Jun)> | It's a interesting question, let me check other language, eg. Kotlin code var x by a::b::c Not sure which behavior it adopt. |
| 20:34 | <Lea Verou> | The main challenge I see is not syntax of the literal, it's how to handle privates. For it to cover forwarding use cases, privates are MVP, but we have no way to represent them in a ComputedPropertyName |
| 20:37 | <Lea Verou> | Perhaps it could end up behaving like an array of objects (once created) to represent the chain, then privates could have e.g. private: true, and if you try to construct a literal with a private property that doesn't exist in your current context the construction itself would throw. |
| 20:38 | <hax (HE Shi-Jun)> | Shouldn't that be a earlyerror? |
| 20:38 | <Lea Verou> | Yes, that's what I'm saying |
| 20:39 | <rbuckton> | You could potentially do this with a decorator and
Where the get/set are replaced with an invocation of the callback that returns a |
| 20:40 | <Lea Verou> | e.g.
which could throw if your current context doesn't include |
| 20:43 | <rbuckton> | I think arrows and
|
| 20:43 | <Lea Verou> | Yes, that would work. I do find it awkward though. |
| 20:44 | <Lea Verou> | Also, there are use cases where you may want to break the chain |
| 20:44 | <Lea Verou> | E.g. "return the last non-null/undefined object" |
| 20:46 | <Steve Hicks> | nicolo-ribaudo: I don't see PKA in this channel, but I was reaching out to Krzysztof Kotowicz about https://github.com/tc39/proposal-dynamic-import-host-adjustment and I think there was a transcription error somewhere since he's not actually mentioned anywhere in that repo. It looks like it's entirely Mike Samuel (who used to be at Google, but is no longer). |
| 20:53 | <hax (HE Shi-Jun)> | Ok, kotlin behave same like ref proposal, the syntax is var x by a.b::c which is much clear the last part is the reference (a::b::c is invalid) |
| 20:56 | <rbuckton> | I'd still rather not mix & or similar inside a property access. We already have . and ?., and have had proposals for other property-access-likes in the past. IMO that's too noisy. |
| 20:59 | <rbuckton> | C, C++, Go, C#, and Rust (among others) use a prefix operand |
| 21:13 | <Lea Verou> | rbuckton: What about a leading
|
| 21:56 | <rbuckton> | Maybe? At first glance it doesn't seem ambiguous, but I'm not 100% sure that's what I would use a leading . syntax for, if we had one. There's a lot of complexity being stuffed into that syntax. IMO, the upside of using x => ref x.#foo.value is that it depends on arrows, which are well known at this point, and ref has a lot more use cases outside of this narrow case, plus it clearly indicates what you have is a Reference. .#foo.value seems almost like partial application, except even that proposal doesn't magically handle References |