00:08:32  * aki_joined
00:09:35  * akirosequit (Ping timeout: 240 seconds)
00:09:35  * aki_changed nick to akirose
01:37:52  * jwaldenquit (Quit: ChatZilla 0.9.92-rdmsoft [XULRunner 35.0.1/20150122214805])
01:57:56  * Guest96698joined
02:04:06  * Guest96698quit (Remote host closed the connection)
02:16:05  * akirosequit (Ping timeout: 240 seconds)
02:16:14  * aki_joined
02:16:38  * aki_changed nick to akirose
03:14:01  <devsnek>jmdyck: nice commit
03:58:37  * guntbert9joined
04:00:29  * guntbert9quit (Remote host closed the connection)
04:01:35  <jmdyck>tx
04:24:28  * aki_joined
04:24:35  * akirosequit (Ping timeout: 272 seconds)
04:24:38  * aki_changed nick to akirose
04:43:49  * jmdyckquit (Remote host closed the connection)
05:06:08  * not-an-aardvarkjoined
05:08:56  * movedjoined
05:12:39  * movedquit (Remote host closed the connection)
05:36:51  * cooledjoined
05:41:15  * cooledquit (Remote host closed the connection)
06:30:41  * aki_joined
06:31:54  * akirosequit (Ping timeout: 244 seconds)
06:31:55  * aki_changed nick to akirose
08:37:51  * aki_joined
08:38:40  * akirosequit (Ping timeout: 256 seconds)
08:38:41  * aki_changed nick to akirose
09:16:48  * joyee_joined
09:17:00  * Domenic_joined
09:17:19  * wycats_joined
09:18:05  * wycatsquit (Ping timeout: 245 seconds)
09:18:05  * zbranieckiquit (Ping timeout: 245 seconds)
09:18:06  * joyeequit (Read error: Connection reset by peer)
09:18:06  * Domenicquit (Read error: Connection reset by peer)
09:18:07  * joyee_changed nick to joyee
09:18:07  * Domenic_changed nick to Domenic
09:22:20  * zbranieckijoined
10:05:52  * not-an-aardvarkquit (Quit: Connection closed for inactivity)
10:44:46  * aki_joined
10:45:38  * akirosequit (Ping timeout: 260 seconds)
10:45:39  * aki_changed nick to akirose
11:11:26  * Sousapro3joined
11:14:59  * Sousapro3quit (Remote host closed the connection)
12:29:35  * jmdyckjoined
12:51:49  * aki_joined
12:52:30  * akirosequit (Ping timeout: 272 seconds)
12:52:31  * aki_changed nick to akirose
12:56:37  * AtumTjoined
13:19:59  * varesa3joined
13:22:26  * varesa3quit (Remote host closed the connection)
14:19:00  * cloudshujoined
14:59:49  * akirosequit (Ping timeout: 272 seconds)
15:00:01  * akirosejoined
15:29:05  * joe_______joined
15:38:13  * joe_______quit (Quit: Page closed)
16:10:30  * sh4nks9joined
16:11:26  * sh4nks9quit (Remote host closed the connection)
16:18:06  * arkainjoined
16:25:43  <arkain>I know I've asked this before, but I think I logged out after I figured everyone to be afk (it was early in the morning). Is there a complete list of the TC39 use cases and requirements that led to the development of proposal-class-fields?
16:35:21  * kg9joined
16:36:43  * Oviusjoined
16:40:22  * kg9quit (Ping timeout: 268 seconds)
16:44:05  * Oviusquit (Ping timeout: 240 seconds)
16:50:52  <devsnek>arkain: its spread out over a lot of time and space
16:51:26  <devsnek>a lot of stuff is in https://github.com/tc39/proposal-class-fields/issues though
16:52:30  <arkain>I've been in and out of that over the past few years.
16:54:09  <arkain>The problem is that while that proposal works as anticipated, it falls short of the expectations of a non-negligibly sized group of developers. It also falls short of the needs of almost all developers who would want to use such a feature.
16:55:38  <devsnek>expectations are meaningless
16:55:44  <devsnek>needs are important though
16:56:13  <arkain>expectations aren't meaningless, but I do agree that they are of limited value.
16:56:15  <devsnek>if you have an issue like that you should open an issue on the repo
16:57:27  <arkain>I've done so several times only to be ignored or dismissed. There have been a few occasions when the concern was addressed and rationally shown to be incompatible with the goals of the proposal. Those cases I don't mind.
16:58:51  <arkain>However, cases like the need for something similar to "protected" which @ljharb in particular doesn't see any need for, is actually a much needed component if any kind of privacy syntax is to be added to the language.
16:58:56  * developersjoined
16:59:52  <arkain>I understand what his argument is on that issue, however it's only a strawman argument that doesn't address the purpose of having a type of "protected" syntax.
17:00:54  <arkain>The one occasion where it was addressed was loosely in the Decorators extension proposal. However, that addressing produced non-viable results.
17:02:01  <devsnek>you can't really do protected in js
17:02:32  <devsnek>well you could but it would be insanely slow and probably have a lot of security issues from edge cases
17:03:23  * developersquit (Remote host closed the connection)
17:03:35  <arkain>Not true.
17:04:07  <arkain>There is a way to accomplish it that is neither slow nor subject to major security issues.
17:04:51  <arkain>Remember that "protected" members are to be thought of a public despite the fact that they won't show on the public externally exposed interface.
17:05:25  <bterlson>arkain: you will find that that intuition is not shared by everyone asking for protected (and indeed what protected even means for JS isn't clear)
17:05:35  <bterlson>if you know how to accomplish it I suggest writing up a proposal
17:06:01  <arkain>I did. https://github.com/rdking/proposal-object-members
17:06:21  * akirosequit (Ping timeout: 240 seconds)
17:06:39  <arkain>It's a complete proposal as far as I can tell. I've even written up a POC that works in ES6.
17:06:53  * akirosejoined
17:08:05  <bterlson>I didn't look in detail, but you should definitely justify why you think protected shouldn't be private-like
17:08:33  <arkain>Thanks for the advice. I'll add that today.
17:09:02  <bterlson>IMO syntax for "friend classes" is a much better fit for JS
17:10:38  <arkain>"friend" while admittedly useful, would require a major rewrite of all ES parsers. Without a 2 pass resolution, mutual friendship would be impossible, but that's one of the major use cases.
17:11:09  <arkain>In most cases though, you can get around the need for "friend" in already well understood ways.
17:11:17  <bterlson>first I've heard of friend requiring a rewrite :-P
17:11:46  <arkain>Btw. Here's a link to a rough justification of why "protected" isn't private-like.
17:11:54  <arkain>https://github.com/tc39/proposal-class-fields/issues/122
17:13:05  <arkain>The problem with mutual friendship is that it requires both objects to exist at the same time. Since friendship could only be applied during declaration, one of the 2 friends will need to be able to befriend a non-existent object.
17:13:18  <arkain>ES is a top-down language
17:14:09  <devsnek>so protected is just private but the symbol is shared between class instances
17:14:15  <devsnek>by your proposal
17:14:39  <arkain>yes... I need to rewrite that part.
17:14:56  <arkain>It's partially true as protected members exist in the private container.
17:15:13  <devsnek>i think you need to shave down the words
17:15:32  <devsnek>https://i2.wp.com/joannapants.com/wp-content/uploads/2018/06/iu.jpeg
17:15:37  <arkain>I can do that... More terse over all?
17:16:22  <bterlson>arkain: fwiw I'm well aware that ES is a top-down language. But you'll find that you can work around the issue you find without rewriting the parser. There's also proposals to allow easier forward references e.g. the `ref` proposal from rbuckton.
17:17:22  <arkain>If the forward references thing doesn't cause an issue, then friend could be built on top of that. I saw that proposal a while back. Could be very useful.
17:18:07  * mt20joined
17:22:25  * mt20quit (Remote host closed the connection)
17:22:47  <Bakkot>arkain: I do not think that it makes sense to implement concepts like protected and friend in JS without first shipping hard private and allowing the ecosystem to explore what needs it does and does not meet. I expect that it will prove to be the case that `protected` and `friend` as they exist in for example C++ are not actually a natural concept for JS, since JS is so much more dynamic.
17:23:47  <bterlson>Bakkot: fwiw when I say friend I don't mean in the sense of any other language, just something approximately like "syntax for sharing symbols" :-P
17:24:26  <Bakkot>bterlson: yeah; I expect people to implement similar things in userland on top of decorators.
17:25:24  <bterlson>sames, and yeah, I'll say it stronger: we must not ship protected/friend without first shipping private + decorators and living with it for a while :-P
17:25:32  <arkain>Bakkot: like you, I don't believe friend is natural to JS. I am not proposing it. However, the need for protected exists **because** of the need for private. This is already a well known fact to those of us who have been constructing libraries of class-like objects
17:25:59  <TabAtkins>Sorry, unrelated topic: Hm, Array subclassing seems to have been totally fixed since I last looked - `class Foo extends Array` correctly returns a Foo instance from the Array generics, etc. Cool! Now if we could just intercept [] sets, so we could typecheck and prevent hole-creation, without needing to invoke the full weight of Proxy machinery, then the WebIDL array-subclass problem would be finally solved in a great way.
17:27:23  <Bakkot>arkain: it is not obviously the case that the need to which you’re referring cannot adequately be met by hard private + decorators.
17:28:59  <arkain>Bakkot: you've already attempted it in your Decorators proposal, showing it to be inadequate. Do you have an idea for how to use a decorator in such a way as to insure that @protected members are only visible to derived objects?
17:29:26  <arkain>If you had a POC of that, I would love to see it.
17:30:41  <Bakkot>arkain: I have something somewhere; give me a second. But note that that was not my claim: I didn’t say “decoratators are definitely good enough”; I said “decorators might be good enough, and we can’t really know without letting the ecosystem sit with them for a while”.
17:30:44  <arkain>As it stands, I've been thinking about it since proposal-class-fields is not likely to be usurped. Over the past year, I have yet to find a way.
17:31:41  <arkain>The only problem is that once it's out there in the wild, there's no way to fix it if it fails to provide what's needed short of making the language a little more convoluted.
17:31:53  <arkain>That's why I raised my own proposal
17:31:59  <Bakkot>Private state stands on its own; it does not require fixing.
17:32:26  <arkain>The approach I'm proposing will definitely provide exactly whats needed and still allow for your decorator proposal to work.
17:32:56  <Bakkot>arkain: https://gist.github.com/bakkot/6924e788ac954fe8302e1c8db429a4af
17:34:30  <arkain>Thanks for the link. It'll take me a little while before I can comment about it.
17:36:25  <arkain>In either case, I believe that support for protected should have a higher priority than that for decorators as it is a feature that will be needed as soon as some form of declarative private lands in the language.
17:38:09  <Bakkot>arkain: re: your proposal: I am extremely strongly against any proposal which allows `private x` as a declaration and which continues to allow `this.x` to refer to a public field named `x`, which yours does. This is basically why I wrote the private syntax FAQ; I’m not sure I can explain it more clearly than is explained there.
17:40:12  <Bakkot>arkain: it is not clear to me why the need for protected state would increase with the introduction of private state; can you expand on that?
17:42:41  <Bakkot>that is, to be specific, it seems to me that there are some cases where you’d want private, and some where you’d want protected, and currently both have to be met with public (or workaround like WeakMap); with the introduction of private, the first of these would be met but not necessarily the second, but I would not expect the number of cases where you want the second to increase over what it already is.
17:49:33  * kepler_mach13joined
17:49:35  * kepler_mach13quit (Remote host closed the connection)
17:53:27  <arkain>Bakkot: I get your reasoning for being against `private x` without `this.x` and as I've stated many times, "I agree". However, that reasoning smells more of emotion than of logic, so I ignore it. Besides, my proposal provides `obj#.x` in its place where `obj#` is the private container. So it essential does give you exactly what you expect once you understand that '#' means "get the private container"
17:54:48  <arkain>Bakkot: On top of that, the approach you provided breaks access methods unnecessarily.
17:55:09  <bterlson>"smells more of emotion than of logic" smells more of "I can't argue the point" than a useful observation (and also needlessly discounts the role of emotion in design) :-P
17:56:12  <arkain>bterlson: I have argued the point on logical grounds many times over the past 2 years only to be met with a response that begins with "I feel that..."
17:56:58  <arkain>as for emotion in a design, that's best left for the cases where there is no reasonable logical argument.
17:58:25  <arkain>The problem with emotion in a logical system is that the logic of the system will not be understood by those who do not share the same emotional view. Hence all the videos about the "wtf's" of ES.
17:59:38  <devsnek>logically `private x` with `this.x`is a confusing mess
18:00:11  <arkain>Confusion is an emotional state.
18:00:42  <arkain>logically, there is not conflict between `private x` and `this.x`
18:01:09  <devsnek>`this.x` `this['x']` and `this[val]`
18:01:14  <devsnek>with `private x`
18:01:15  <arkain>especially if `private` means stored in the private container owned by "this"
18:01:30  <devsnek>or `instance.x`
18:01:36  <devsnek>outside the class
18:02:15  <arkain>devsnek: all public references. To make them private, add a `#` before the `.`
18:02:39  <arkain>.. and before the `[`
18:02:48  <devsnek>why were you arguing about `private x` and `this.x` then 🤔
18:03:01  <devsnek>if we all agree that #. is good
18:03:15  <devsnek>or .#
18:03:22  <arkain>I thought it was a continuation of Bakkot's argument
18:03:55  <TabAtkins>As devsnek pointed out, there is a logical conflict. More importantly, tho, "no logical conflict" just means "this idea isn't logically contradictory"; it does *not* mean "this is a reasonable idea that must be considered as a major contender in the discussion". There are lots and lots of "no logical conflict" possibilities in any API design; many are still not good on design grounds, because design *is* an
18:03:55  <TabAtkins>emotional/"feel"-based process.
18:04:18  <devsnek>also this ^
18:04:59  <bterlson>Any design is fundamentally empathy in practice. Just my experience.
18:06:20  <arkain>Then can anyone explain precisely what the "logical conflict" is such that there can be both a "logical conflict" and "no logical conflict" concurrently? That very statement is illogical. It would be better if any of you had claimed that this was a "rational conflict". I could have accepted that as it is also one for me given my history with other programming languages.
18:06:44  <arkain>However, I accept that ES is not the same as those other languages and that the programming paradigm will be a little different.
18:07:01  <arkain>My proposal simply minimizes those differences.
18:07:50  <ljharb>i don't think minimizing those differences is automatically a good thing.
18:07:52  <TabAtkins>The conflict was with the `private x` and `this.x` thing. I'm very confused about that at this point, tho, since you seem to be saying that `this.x` doesn't refer to the private name.
18:07:57  <ljharb>different things should look different.
18:08:33  <ljharb>put another way, things should only look similar if they are similar.
18:09:41  <arkain>ljharb: true. Fundamentally, the meaning of a private field in C++, Java, and my proposal are not different. Likewise true for protected. What is different is how it is to be implemented in the language.
18:10:02  <arkain>Hence, it is safe to use the keywords, knowing people will understand the meaning.
18:11:13  <arkain>Bakkot, I haven't forgotten to give you a reason. It's coming.
18:11:54  <arkain>The class fields proposal explains the use of # as a language backed replacement for the '_' convention.
18:12:57  <arkain>This will likely lead some people to do a wholesale find and replace of `_` variable names in their libraries to make them private. Not everyone will do this, but some will.
18:13:10  <devsnek>its not because of the underscore convention
18:13:19  <arkain>This will cause them to notice that they've broken some of their code.
18:13:29  <devsnek>its because there's no performant way to track object privilege on normal accessors
18:14:02  <devsnek>all sorts of weird situations come out of them being the same accessor due to javascript being javascript
18:14:08  <arkain>devsnek: I never said it was because of the underscore convention. I'm merely recounting how proposal-class-fields describes the meaning of the '#'
18:14:12  <devsnek>adding methods to prototypes, computed access, etc
18:14:35  <arkain>devsnek: and the usage....
18:14:41  <ljharb>arkain: they are different. in java etc, they're access levels
18:14:53  <ljharb>arkain: in JS, there's no such thing as access levels. there's only reachable - public - and unreachable - private.
18:15:18  <ljharb>and if the `private` keyword makes people think there should be `protected`, then that's a pretty big reason imo to avoid the `private` keyword.
18:15:41  <ljharb>because "access levels" is simply the wrong mental model to apply in JS
18:15:53  <ljharb>(imo)
18:16:06  <arkain>ljharb: That's only true given proposal-class-fields. If proposal-object-members goes through instead, there will indeed be access levels whose fundamental meaning and usage match that of Java.
18:16:45  <arkain>ljharb: It's not the keyword, it's the feature that will leave people looking for protected support.
18:17:15  <ljharb>"matching java" is not a good motivation for me.
18:17:25  <arkain>It's not a motivation at all for me
18:17:28  <ljharb>i think JS should set its sights much much higher than "how java does it"
18:17:32  <devsnek>i think js has so many fundamental differences from languages with access levels that its not worth doing for the sake of doing
18:17:57  <ljharb>that people will think they *want* protected doesn't mean it's appropriate for it to exist
18:18:50  <arkain>Then why is it important for some method of declaratively producing private fields to exist?
18:19:28  <arkain>The same rationale you would apply to my question also applies to protected fields
18:19:30  <ljharb>because private - unreachability - already exists in the language, for everything except class instances
18:19:38  <ljharb>thus, the only place it really needs to be added is class instances
18:19:53  <ljharb>(variables inside a closure, is the existing mechanism)
18:20:15  <arkain>ljharb: not true. class instances can indeed harbor protected fields via a weakmap
18:20:27  <ljharb>i think you mean private, but yes, i know
18:20:35  <arkain>oops
18:20:41  <ljharb>arkain: but that's not a lexical mechanism.
18:20:51  <arkain>I know
18:20:56  <ljharb>ok so, that's what this adds
18:21:09  <ljharb>"protected" already exists: stick an underscore in front of your property name, or use a symbol
18:21:27  <arkain>The same is true for protected. They can also be implemented via weakmap, and there's no lexical mechanism for that either.
18:21:53  <ljharb>i'm confused why you'd bother using a weakmap if you're going to let any subclass access it
18:22:08  <ljharb>but either way, there's no lexical mechanism for protected *everywhere else* either
18:22:10  <arkain>ljharb: sticking an '_' in front of your property name does not prevent that field from existing on the external interface of the object.
18:22:27  <devsnek>anything with an instance of your class can access your protected members
18:22:30  <ljharb>the external interface is everything observable. including the existence of protected fields, which can be observed by subclassing it.
18:22:42  <devsnek>it would actually be safer to use a weakmap lol
18:22:44  <ljharb>making something protected in no way removes it from your public interface, it just makes it slightly harder to fine.
18:22:45  <ljharb>*find
18:23:04  * NightMonkey0joined
18:24:24  * NightMonkey0quit (Remote host closed the connection)
18:26:26  <ljharb>basically, any definition of "public interface" is one of two things: either it's only the things that are possible, or it's only the subset of possible things you declare are suported
18:26:27  <arkain>The external interface of an object is anything I can access without jumping hoops(adding code that doesn't match /\w+((\.\w+)|(\[(["'`]).+\4\]))*/. Subclassing is jumping hoops.
18:26:30  <ljharb>no
18:26:35  <ljharb>hoops are irrelevant
18:26:47  <arkain>Not true
18:26:50  <ljharb>symbols are public too, even tho Object.getOwnPropertySymbols is a hoop
18:26:57  <TabAtkins>what... is that regex
18:26:59  <ljharb>and if hoops make it not public, then "use a symbol" and boom, you're done
18:27:22  <ljharb>arkain: so again, either your public interface is "only reachable", or it's "some arbitrary subset of reachable that you decide for yourself"
18:27:32  <arkain>The fact that there is no lexical mechanism for declaring a private field means you have to jump hoops to do so. That doesn't mean it's impossible.
18:27:34  <ljharb>if it's the latter, you shouldn't have syntax to support that - it's just your homegrown convention
18:27:58  <ljharb>arkain: right, and "hoops" are irrelevant to privacy. if it's possible to make it unreachable and unobservable, it's private, if not, it's public.
18:28:16  <ljharb>you are more than welcome to invent your own definition of "public interface" for any code you write, of course
18:28:26  <ljharb>but the language shouldn't be supporting some arbitrary definition
18:31:21  <arkain>ljharb: I agree. However, we seem to have differing opinions on what constitutes the "public interface" of an object. Let me try again. If all slots of an object beyond the ones that can be found on a default object and added or removed via Object.defineProperty and delete were removed from an object, then all remaining items constitute the public interface of that object.
18:32:17  <arkain>A protected field should not appear in the public interface thusly defined.
18:32:25  <ljharb>the public interface includes all observable behavior.
18:32:33  <ljharb>it's not just "the property names", it's "what the functions do"
18:32:35  <ljharb>also
18:32:40  * ilerajoined
18:32:53  <bterlson>ljharb: *cough*
18:33:32  * ileraquit (Remote host closed the connection)
18:34:03  <arkain>ljharb: can I take this to mean I should be using a different expression other than "public interface"? If so, I can make the appropriate changes in my proposal.
18:35:52  <ljharb>arkain: sure, let's stop taking about the interface - "publicly observable interface and semantics" imo is the "public API"
18:37:29  <arkain>Ok, then I'll restate it: While a protected field is a part of the object's public API, it will not be an "own property" of the object any more than a private field will be.
18:37:49  <arkain>Does that make it clearer?
18:37:52  <devsnek>sure
18:38:01  <devsnek>but "own property" is pretty arbitrary
18:38:11  <arkain>???
18:39:25  <devsnek>own properties don't even make a complete public api
18:40:00  <ljharb>public class methods aren't own properties either
18:40:58  <arkain>x is an "own property" of y iff (Object.getOwnPropertyNames(y).concat(Object.getOwnPropertySymbols(y)).indexOf(x) !== -1)
18:41:19  <ljharb>or just `Object.prototype.hasOwnProperty.call(obj, key)`
18:41:24  <ljharb>no need to make it overly complex
18:41:31  <arkain>&& x != "__proto__"
18:41:43  <arkain>true
18:42:12  <arkain>I thought "own property" was a non-arbitrary phrase.
18:43:29  <arkain>Does this at least clarify the purpose of "protected" as I'm proposing?
18:43:54  <devsnek>i don't think there are ambiguity before
18:44:30  <arkain>There was due to conflicting meanings of "public API"
18:44:50  <arkain>What I meant was not what was understood by others. Hence the need for clarification.
18:47:21  <devsnek>i think the point was no matter what your own definition of public api is, it has to be generic for all of js, which yours isn't
18:47:51  <arkain>fair enough. That's why I won't use "public API" in that way anymore
18:48:37  <arkain>Now given my restatement above for the meaning of "protected" are there still objections?
18:48:53  <ljharb>yes
18:49:15  <ljharb>i see no value in something that's "public but behind that curtain over there in the corner, just ignore the curtain"
18:49:15  <arkain>Thought so. lets here them.
18:49:25  <ljharb>if it is reachable, it is public. full stop.
18:49:50  <ljharb>for "protected" to exist i'd want to see an explanation of a way to make something unreachable, but somehow different than "explicitly shared private"
18:50:12  <ljharb>and so far the only "logic" i see for protected is "other languages have it, JS should too".
18:50:26  <bterlson>explicitly shared private and protected can be isomorphic :-P
18:51:18  <devsnek>like i can see the jump to accessing private properties of other instances
18:51:24  <devsnek>but i don't know what i would actually do with that
18:51:24  <arkain>bterlson: They **are** isomorphic
18:51:25  <ljharb>sure, i'd love to hear some reasoning for why extra syntax is needed for explicitly shared private
18:52:21  <arkain>Class hierarchies are the reason.
18:53:07  <ljharb>go on
18:53:38  <ljharb>assuming private fields land as-is, can you show me some code that illustrates your use case, and then show me example syntax that is needed to make it easier?
18:53:47  <arkain>It is often the case that when writing them, some code from a class needs to be accessible to the subclasses. However, the developer may not want that logic to be openly accessible via the own properties of any such objects.
18:54:44  <ljharb>arkain: it can already be accessible via a class instance method, which is on the prototype and not "own"
18:54:52  <arkain>I can certainly give examples. I write these kind of things all the time.
18:54:58  <ljharb>for example, `forEach` is not an own property of `[]`
18:55:22  <arkain>nice catch. I need better wording there.
18:55:43  <ljharb>regardless, there's no need to put the exposed code directly on anything
18:55:59  <ljharb>the base class can have a static method, that takes an instance (of itself or a subclass) as an arg, and can do whatever it likes
18:56:09  <ljharb>and it can use private fields to manage all that data
18:56:12  <arkain>try "... via the own properties the object or its prototype chain"
18:56:22  <ljharb>ok, that's "a property"
18:56:50  <arkain>yeah. I gotta work on being more terse when thinking formally.
18:57:04  <ljharb>i'd say think less formally, this is just basic JS terminology
18:57:24  <ljharb>so like `class Foo { #id; static compareIDs(a, b) { return a.#id === b.#id; } }` - you can have `class Bar extends Foo { }` and then `Foo.compareIDs(new Foo(), new Bar())` and it will work just fine
18:57:37  <ljharb>now the instances don't have a `compareIDs` property anywhere
18:57:45  <ljharb>but the code is shared, and works down the entire class hierarchy
18:58:38  <arkain>trying "... via a property of the object or its constructor"
18:59:20  <arkain>I think that covers the whole range I'm considering.
18:59:27  <ljharb>ok, so how about this:
19:00:14  <ljharb>` export default class Foo { #id; static compareIDs(a, b) { return a.#id === b.#id; } }; const compare = Foo.compareIDs; export { compare } delete Foo.compareIDs;` - you can have `import Foo, { compareIDs } from './foo'; class Bar extends Foo { }` and then `compareIDs(new Foo(), new Bar())` and it will work just fine
19:00:19  <ljharb>next constraint?
19:00:31  <ljharb>(i messed up my import name there but the gist should be clear)
19:04:06  <arkain>correcting... "... need to be accessible only to the declaring object and sub-objects via prototype extension. ..."
19:05:34  <arkain>.... baka.... "prototype inheritance". Still fighting myself.
19:06:47  <ljharb>that's already the case above
19:06:59  <ljharb>only a subclass will have the private field; it will throw on any other object.
19:07:08  <arkain>not really. If it is, then the example you gave is a leak.
19:07:20  <ljharb>an explicit intentional leak yes, which is permitted
19:07:44  <ljharb>the compareIDs function was lexically defined inside Foo's class body, so it has access.
19:09:05  <arkain>It fails in that compareIDs is not available on an instance of Foo
19:09:47  <arkain>It's about the objects, not the factories that produce them.
19:10:15  <ljharb>i'm confused, fails how
19:10:26  <ljharb>the constructor is the factory, and you said "not on the constructor"
19:10:42  <ljharb>so if it's about just the instances, then a static method is sufficient
19:10:54  <ljharb>and if not, then extracting and removing the static method, as i showed above, is sufficient.
19:11:33  <arkain>You've been giving me a static member. The point of a protected member is to be available on a instance of a class (or on an object instance regardless of factory in my proposal)
19:12:47  <ljharb>right but that's not how JS works
19:12:51  <ljharb>if it's on the instance, it's observable to everyone
19:12:59  <arkain>So compareIDs should be accessible from within a method of Foo, and within a method of Bar since it inherits Foo.
19:13:01  <ljharb>or else it's a private field, and it's not :-)
19:13:06  <ljharb>ok so i think i understand what you want
19:13:19  <ljharb>you want syntax like private fields, but that implicitly makes the fields accessible to subclasses
19:13:43  <arkain>yes. That's the meaning of Protected.
19:14:00  <ljharb>ie, `class Foo { #private; ##protected; /* both accessible here */ } class Bar extends Foo { /* only protected accessible here */ }`
19:14:02  <arkain>Hides like private, shares with children
19:14:18  * aki_joined
19:14:19  <arkain>exactly
19:14:24  * akirosequit (Ping timeout: 272 seconds)
19:14:28  * aki_changed nick to akirose
19:14:29  <ljharb>to me that seems very confusing (unrelated to syntax); how would the author of Bar even know that field was available?
19:14:36  <arkain>You can see an example of that in action
19:15:05  <arkain>https://github.com/rdking/proposal-object-members/tree/master/POC
19:15:23  <arkain>Look at example.js there
19:15:56  <arkain>There are detailed tests in the "tests" directory.
19:16:06  <ljharb>that's pretty confusing; do you have an example that uses syntax?
19:16:19  <ljharb>ie, what would the code look like if your proposal landed
19:17:01  <arkain>Would it help if I made a copy of example.js with appropriate syntax?
19:17:51  <arkain>Give me a few minutes and I'll have it done.
19:18:50  <ljharb>sure
19:18:57  * Guest12107joined
19:25:21  * Guest12107quit (Ping timeout: 244 seconds)
19:30:54  <arkain>It's there now
19:31:02  <arkain>example.ESNext.js
19:33:59  * Havvyquit (Read error: Connection reset by peer)
19:38:28  * jwaldenjoined
19:42:41  <arkain>I just added the output of running the POC as "example.output.txt"
20:24:56  * Sousapro3joined
20:29:42  * Sousapro3quit (Remote host closed the connection)
20:52:12  * wget18joined
20:55:46  * wget18quit (Killed (Unit193 (Spam is not permitted on freenode.)))
20:57:21  <ljharb>arkain: i get it, but i think it'd be super weird to have `this#.field3` work when there's no declaration for it lexically, and there's no way to determine it's there via reflection.
20:59:09  <arkain>That's just how protected works
20:59:17  <ljharb>sure
20:59:21  <ljharb>but i find it weird
20:59:46  <ljharb>so what's your motivating use case?
21:00:09  <ljharb>where it's critical that the info not be on the public interface, but it's acceptable that anyone could subclass and get access to monkey with your protected fields
21:01:28  <arkain>Object hierarchy libraries, especially UI type libraries. The notion of a UI "widget" often depends on being able to inherit customizable functionality from a superclass
21:01:54  <arkain>That customizable functionality is defined by a protected API
21:02:08  * Havvyjoined
21:02:15  <arkain>The public API is what end-users manipulate.
21:02:58  <arkain>In general, the use cases are identical to those found in other languages supporting the keyword.
21:03:00  <ljharb>that's already achieved all over the place with an underscore, or with symbols, tho
21:05:04  <arkain>The only problem is that developers are manipulating what should be a protected interface without it being very clear that they are doing so. '_' is little more than a hint, and Symbol isn't significantly different than `enumerable: false`
21:05:13  <TabAtkins>Yeah, that's handled great by "don't touch this" convention. No need for the lexical hiding of `private`.
21:05:19  <arkain>... when used like that.
21:06:25  <arkain>Symbol's best use is for its unique value, for cases when you need a property name that's 100% certain not to be used by anything else.
21:20:34  * akirosequit (Ping timeout: 244 seconds)
21:21:22  * akirosejoined
21:39:03  * arkainchanged nick to arkain_afk
23:15:29  * mrBlaQ10joined
23:18:00  * mrBlaQ10quit (Remote host closed the connection)
23:28:19  * aki_joined
23:28:27  * akirosequit (Ping timeout: 240 seconds)
23:28:31  * aki_changed nick to akirose