00:52 | <Axel Rauschmayer (self-employed)> | Sorry, off-topic, but could we do a quick test if showing my slides works? |
00:55 | <Robert Pamely> | Is the video conference live? |
00:56 | <Robert Pamely> | I see waiting for host |
00:56 | <bterlson> | it is not started yet |
00:56 | <Axel Rauschmayer (self-employed)> | Me too. We need a host, yes. |
00:56 | <bterlson> | waiting for an igalian to do so :) |
00:56 | <Robert Pamely> | ok thanks Brian |
00:56 | <Axel Rauschmayer (self-employed)> | Hehe |
00:59 | <Ashley Claymore> | Sorry, off-topic, but could we do a quick test if showing my slides works? |
00:59 | <Axel Rauschmayer (self-employed)> | Yeah, already did that (the screen sharing background helps with testing). |
01:01 | <littledan> | I guess you can try screen sharing now? |
01:09 | <littledan> | Are we ready to get started? |
01:09 | <shu> | haven't we already started? |
01:10 | <bakkot> | we have in fact already started |
01:10 | <snek> | axel has been presenting for like 5 minutes |
01:14 | <littledan> | Oh! A problem on my end |
01:15 | <Michael Ficarra> | what is meant by "a wrapping API" here? |
01:16 | <ljharb> | isn't Iterable.from() already a wrapping API? it's just that most builtin iterators are/will be pre-wrapped |
01:16 | <bakkot> | something like Jquery |
01:16 | <bakkot> | where you do $(document.querySelectorAll(...)) and then get a new thing that has a bunch of helper functions |
01:17 | <Michael Ficarra> | how is that different than what we do? |
01:17 | <bakkot> | you don't need to wrap most of the time |
01:17 | <HE Shi-Jun> | A real example of "wrapping API" |
01:17 | <HE Shi-Jun> | Emitter proposal |
01:18 | <HE Shi-Jun> | https://github.com/tc39/proposal-emitter |
01:18 | <bakkot> | like if you do map.values().filter() there's no explicit wrapper |
01:18 | <ljharb> | right, builtins are "pre-wrapped" |
01:18 | <ljharb> | (or some better way to describe it) |
01:18 | <Michael Ficarra> | yeah, that's kinda my mental model |
01:19 | <HE Shi-Jun> | Emitter proposal also use function style. |
01:19 | <HE Shi-Jun> |
|
01:20 | <Michael Ficarra> | that's applicative style, no? |
01:21 | <ljharb> | Axel Rauschmayer (self-employed): re builtin modules, pending that proposal advancing, short answer is no, not in the cards (shu's queue item covers this also) |
01:23 | <Michael Ficarra> | it's iterable ONCE, which is the important point |
01:24 | <Michael Ficarra> | iterators are kind of lying by implementing Symbol.iterator |
01:25 | <shu> | snek: wait, you are in favor of using iterable helper functions as Axel proposed? |
01:26 | <Michael Ficarra> | shu: no I think they were saying iterator helpers as functions (conditional on pipe operator) |
01:26 | <shu> | we need a better word than "functions" here |
01:26 | <Michael Ficarra> | non-this-value-users |
01:27 | <ljharb> | "standalone functions" vs "methods" imo |
01:29 | <shu> | yes that's good |
01:31 | <ljharb> | Axel Rauschmayer (self-employed): for clarity; consensus typically means "some explicit yes's and no explicit no's" and does not imply or require universal enthusiasm :-) |
01:32 | <rbuckton> | I'm primarily in favor of the standalone function approach because its more flexible and is composable with third-party packages without the need for prototype patching (which is obviously bad). Yes that puts more of a dependency on pipeline, but I think pipeline can advance once the topic variable issue is addressed. |
01:34 | <snek> | to be clear i was concerned about wasting work on consensus, not work on spec text |
01:35 | <Michael Ficarra> | oh god, a superclass of all collection types would be as bad an idea as Object.prototype already is |
01:36 | <shu> | haha oh no please no |
01:36 | <snek> | class TCPConnection extends Collection |
01:36 | <ljharb> | we could just call it FragileBaseClass |
01:36 | <ljharb> | oh wait sorry wrong channel |
01:36 | <Michael Ficarra> | why do so many people have this same bad idea? |
01:37 | <rbuckton> | ecosystem can/does have chaining-style via wrapping. And given the limited number of helper methods I'm still more likely to reach for 3rd-party. |
01:38 | <Michael Ficarra> | rbuckton: we have plans to add a lot more |
01:38 | <Michael Ficarra> | remember the current proposal is what we consider "minimal" |
01:39 | <ljharb> | so many more |
01:39 | <Michael Ficarra> | okay not that many |
01:39 | <snek> | i closed a lot of issues/prs for more methods |
01:39 | <Michael Ficarra> | like a dozen? |
01:40 | <bakkot> | https://github.com/tc39/proposal-iterator-helpers/issues?q=is%3Aissue+is%3Aclosed+label%3A%22good+follow-on+proposal%22 |
01:40 | <rbuckton> | But until you do, and as long as there is an iterator helper I need that isn't in that list, I'm still bouncing between methods and functions. Until we have pipeline, but if we have pipeline I'd still rather have functions. |
01:42 | <Michael Ficarra> | we have 15 min underflow during this session, we might want to just let this topic go over by 15 min? |
01:43 | <Michael Ficarra> | especially given that this presenter is an invited expert, it would be nice to be more lenient with the timebox |
01:43 | <Anthony Bullard> | I don't think these functions would be global, correct Axel Rauschmayer (self-employed) ? |
01:43 | <Anthony Bullard> | I'm assuming they would be in a global namespace, like Math |
01:43 | <ljharb> | what would we call it tho - "Iterable" isn't a "thing", it's a trait |
01:44 | <rbuckton> | I have all of these as functions (@esfx/iter-fn and @esfx/async-iter-fn ), and wrapping via a Query class (@esfx/iter-query and @esfx/async-iter-query ). All of these are iterable (multi-shot if source returns a new itererator each time, single shot if the source returns the same iterator each time). |
01:44 | <ljharb> | to be fair, iterators aren't a thing either, but the helpers proposal makes a wrapped iterator A Thing, via Iterator.from |
01:44 | <Anthony Bullard> | That's a great point, but is there a concern with there being a global for the trait? |
01:44 | <ljharb> | it's just weird |
01:45 | <ljharb> | because wrapping iterators makes sense; wrapping iterables i'm not sure does |
01:45 | <ljharb> | Iterable.from(set) wouldn't be a Set, for example |
01:45 | <rbuckton> | And if you do Iterator.from(x).map() , Query.from(x).map() is pretty much the same. |
01:45 | <Anthony Bullard> | I agree, but that is kind of the way that Rust traits get compiled down |
01:46 | <bakkot> | C#'s IEnumerable is reusable (I believe), but that has super weird performance implications |
01:46 | <Anthony Bullard> | No, it's an Iterable, like the name of the namespace - not that class or type, but a type that implements that trait |
01:46 | <ljharb> | JS doesn't have a type system like that tho |
01:47 | <Anthony Bullard> | It would be strange for functions in Iterable namespace to return a Set |
01:47 | <snek> | i was going to mention this on the queue but how we explained reusability in the past is via functions. for example how do you make for..of reusable, you wrap it in a function that you call multiple times. |
01:47 | <bakkot> | it would also be strange for them to return things that are not reusable |
01:47 | <Michael Ficarra> | I wish this proposal hadn't conflated using the function style with the change to iterables; using functions is a reasonable request, but operating on iterables is not |
01:48 | <snek> | i was going to mention this on the queue but how we explained reusability in the past is via functions. for example how do you make for..of is not relevant itself, you could be manually consuming an iterator or you could be using a generator or whatever, you just end up with a nice abstraction boundary of a function. this was also a big point with Number.range if anyone remembers that. |
01:48 | <bakkot> | you could extend iterator.prototype and have FancyIterator.from(thing).fancyMethod() etc |
01:48 | <bakkot> | seems fine |
01:48 | <ljharb> | re shu 's queue item - function filter(iterable, filterer) { return Iterator.from(iterable[Symbol.iterator]()).filter(filterer); } i think? |
01:48 | <Anthony Bullard> | I agree with that Michael Ficarra . I wish static methods or namespaced sets of functions are a better approach - and much better when we get pipes |
01:48 | <rbuckton> | I could imagine a
|
01:49 | <bakkot> | but also, the language has had built-in Array.prototype.map forever while underscore had _.groupBy or whatever, and that was fine; the ecosystem things don't necessarily need to look like built-in things |
01:49 | <bakkot> | (to shu's point) |
01:51 | <bakkot> | also the language will always have Array.prototype.map , so it's not like we can avoid having method-based things in the stdlib at this point |
01:51 | <rbuckton> | The .use concept could work with Iterator , though (i.e., subclass Iterator , mix in and wrap the provided methods). |
01:51 | <shu> | i think as a way of choosing defaults for the standard library, i see no compelling reason aside from taste to deviate from what we have been doing since the language's inception with prototype methods |
01:51 | <shu> | the functional style is easily polyfilled |
01:51 | <shu> | let those adherents import a library, that seems sufficient? |
01:53 | <ljharb> | if/after pipeline has landed, i think there will be compelling reasons. but until then, i agree that there isn't. and i don't think proposals should wait for that. |
01:53 | <bakkot> | s/after/if/ |
01:53 | <ljharb> | yes thanks, edited |
01:53 | <rbuckton> | let those adherents import a library, that seems sufficient? Iterator.prototype , makes for hard to read code. |
01:53 | <ljharb> | it wouldn't be hard to read with pipeline tho :-) |
01:53 | <Michael Ficarra> | ljharb: just like we shouldn't have to wait for a way to list all intrinsics, right? 😉 |
01:53 | <shu> | rbuckton: that seems unavoidable |
01:54 | <shu> | JS is not a functional style language |
01:54 | <shu> | it has some combinators here and there |
01:54 | <rbuckton> | if/after pipeline has landed, i think there will be compelling reasons. but until then, i agree that there isn't. and i don't think proposals should wait for that. |
01:54 | <ljharb> | yep! i'm on your side for that one, altho ofc we still need that "way" |
01:54 | <Michael Ficarra> | ljharb: I hope to hear your support for that later then 🙂 |
01:55 | <bakkot> | if you want to use more things in a method-based style, you can write a thing extending Iterator.prototype and put more methods on it |
01:55 | <bakkot> | that works fine |
01:55 | <bakkot> | Iterator has no slots |
01:55 | <bakkot> | and will never have slots |
01:55 | <ljharb> | even if it did, extending Iterator would give you them |
01:56 | <bakkot> | Bradford Smith: re your queue topic, you don't have to implement a bunch of stuff, you just __proto__: Iterator.prototype |
01:57 | <bakkot> | to be clear, I am very, very opposed to function-based style even in a world in which we have pipeline |
01:57 | <bakkot> | I do not think pipeline meaningfully changes this conversation |
01:58 | <HE Shi-Jun> | to be clear, I am very, very opposed to function-based style even in a world in which we have pipeline |
01:58 | <bakkot> | Array.prototype.map already exists, and will always exist |
01:58 | <bakkot> | mapping over iterators should work like mapping over arrays |
01:59 | <bakkot> | not with completely different style and completely different syntax |
01:59 | <shu> | the "consistency" arguments presented so far are very myopic IMO |
01:59 | <Jack Works> | if you want to use more things in a method-based style, you can write a thing extending Library1Iterator.prototype and Library2Iterator.prototype |
01:59 | <shu> | ISTM to boil down to "my code is already functional style, it'd be nice if i didn't need a 3p library to keep that style" |
01:59 | <shu> | i daresay that's a minority? |
02:01 | <Jack Works> | you must see this https://github.com/fantasyland/fantasy-land 😂 |
02:01 | <ljharb> | both clauses of that are a minority |
02:01 | <ljharb> | people who avoid third party libs, and codebases that are predominantly functional |
02:01 | <bakkot> | you must see this https://github.com/fantasyland/fantasy-land 😂 |
02:02 | <bakkot> | Michael Ficarra in particular |
02:05 | <rickbutton> | if not pipeline, the :: call syntax would also alleviate some of this burden of swapping styles |
02:05 | <rickbutton> | don't remember what the feeling on this at the time was tho |
02:06 | <waldemar> | A bigger problem than style is semantics. See the problem that Kevin and I raised. |
02:11 | <HE Shi-Jun> | If talking about semantics , I also have the concern, should we extend Iterator too much? IMO, iterator should be simple and only use as underlying mechanism, why not use a separate concept for data transformation? Like Java Stream, or Emitter proposal? |
02:13 | <bakkot> | java streams would have been on iterator if they could have |
02:13 | <bakkot> | but the existing iterator interface, in Java, has .remove and stuff |
02:13 | <bakkot> | and has distinct hasNext and next methods |
02:13 | <bakkot> | which are awkward with helpers |
02:13 | <bakkot> | those facts are the only reason Stream exists |
02:14 | <bakkot> | I can try to track down the mailing list discussions from when Stream was introduced |
02:14 | <bakkot> | but we don't have those problems, so we don't need to introduce a new thing |
02:14 | <bakkot> | which is nice |
02:16 | <HE Shi-Jun> | But we have other problems like Iterator interface. There are confusions on what Iterator means in the ecosystem. For example, Iterator helpers actually require TS to change the definition of Iterator. |
02:17 | <bakkot> | That seems like an extremely minor problem, given that we're designing a language which will be in use for decades |
02:17 | <HE Shi-Jun> | I don't think it's a "extremely minor problem". |
02:17 | <bakkot> | TS will rename Iterator to IteratorLike |
02:17 | <bakkot> | it will be fine |
02:19 | <Jack Works> | it will be a ecosystem breaking change |
02:19 | <HE Shi-Jun> | Yeah, TS always have the way to do incompatible change, but obviously it have cost ,not only TS itself, but also the whole ecosystem |
02:19 | <ljharb> | sure. but that's kind of an unavoidable cost when building on top of a standard, outside that standard, no? |
02:19 | <bakkot> | I suspect there are relatively few things which use the Iterator type, and it is a very easy migration to do |
02:20 | <Jack Works> | use Iterator as IteratorLike, and ABikeSheddingNameIterator as Iterator is good IMO |
02:20 | <bakkot> | relative to the design of the language for the next several decades, the cost of that particular breaking change is small |
02:20 | <HE Shi-Jun> | Again, it's not only TS problem, we also change the Iterator in the spec from a Interface(protocol) to concrete class (prototype). |
02:20 | <ljharb> | in the spec it'd be both. it's already both, it's just that the concrete class isn't really exposed to users, and this proposal would expose it. |
02:20 | <bakkot> | speaking as editor of the specification, the name of the interface in the spec is basically the lowest possible priority |
02:21 | <Jack Works> | relative to the design of the language for the next several decades, the cost of that particular breaking change is small |
02:21 | <bakkot> | Jack Works |
02:21 | <bakkot> | that particular breaking change was much more serious |
02:21 | <rbuckton> | I suspect there are relatively few things which use the Iterator directly, changing that would be breaking, but the interface Iterator doesn't have to align with the value Iterator . |
02:21 | <HE Shi-Jun> | speaking as editor of the specification, the name of the interface in the spec is basically the lowest possible priority |
02:23 | <rbuckton> | In TypeScript? Actually there are a fair amount of folks using |
02:24 | <ljharb> | sure, but that's what Iterator.from is for - and iterator helpers would push all the authors of those iterator-likes to in fact make them have both of those things |
02:24 | <bakkot> | I have myself written iterators which don't inherit from Iterator.prototype, but writing iterators manually is a pretty unusual thing to do, and having to add __proto__: Iterator.prototype to such things in the future is not such a large cost, I think. |
02:27 | <HE Shi-Jun> | I guess "{proto: Iterator.prototype}" doesn't work in some runtime (deno?) |
02:27 | <bakkot> | it does |
02:27 | <bakkot> | deno deletes the Object.prototype accessors |
02:27 | <bakkot> | not the syntax |
02:27 | <bakkot> | it's a required part of the spec |
02:27 | <Jack Works> | syntax works everywhere |
02:27 | <rbuckton> | ljharb: re: your comment in the queue. With the exception of yield* "abc" , for(const x of "abc") , and ..."abc (i.e., very explicit actions on a supplied iterable), I really do think any new API that accepts an Iterable should restrict it to Object iterables. |
02:29 | <rbuckton> | Pretty much every other use case where you end up spreading a string is probably a bug (except Array.from ). I'd argue that if you wrote new Set(value) and value was a string, its most likely a bug. If a new API accepted an iterable argument, I'd push hard for requiring you to do [..."abc"] if you really wanted to pass in code points. |
02:31 | <rbuckton> | forEach shouldn't be in the middle of a chain |
02:31 | <rbuckton> | that would be something like .tap . |
02:32 | <bakkot> | for tap , see this thread, particularly my last comment: https://github.com/tc39/proposal-iterator-helpers/issues/13#issuecomment-1210164187 |
02:32 | <msaboff> | Justin Ridgewell: what is your abbreviation? |
02:32 | <Justin Ridgewell> | The undefined return value is my my hated part of Array.p.forEach . |
02:32 | <Justin Ridgewell> | JRL |
02:33 | <bakkot> | https://github.com/tc39/notes/blob/6f7e075341e435f22777b07a3ee5141442d2d8a7/delegates.txt#L231 |
02:35 | <rbuckton> | I disagree, I feel indexed() is over complicated, and passing in a counter is much easier to reason over and better for refactoring. The fact that we pass a counter and not the source as a 3rd arg like we do for Array is indicative enough that its not an index. |
02:36 | <ljharb> | erights: so i'm looking, and now i can't find the file i remember looking at - certainly you'll have https://github.com/ljharb/get-intrinsic/blob/main/index.js, but in test262 it's all single lines of code in individual test files, like https://github.com/tc39/test262/blob/6e61dd7754e7c94ebcf3ee679cb8db3c54a37b50/test/built-ins/ThrowTypeError/length.js#L16-L19 - which isn't a single location, but at least means there's a canonical way to "get at" the intrinsic |
02:36 | <ljharb> | we don't provide the source on array reduce/reduceRight, either, and that argument is rarely used anyways, so i don't think that indicates anything |
02:37 | <rbuckton> | I've taken to think of the "iterator helpers" as "one shot iterable helpers that happen to be on Iterator.prototype and can be accessed by any iterable using Iterator.from()" |
02:37 | <ljharb> | i agree with that mental model, but i don't think that speaks for or against "counter"? |
02:38 | <rbuckton> | i agree with that mental model, but i don't think that speaks for or against "counter"? |
02:40 | <bakkot> | rbuckton: I expect to do a fair amount of document.querySelectorAll(...).values().map().find() etc |
02:40 | <rbuckton> | There's a difference in intention. .reduce is an aggregation operation producing a scalar value. It's perfectly reasonable to expect .map and .filter to care about a counter. .map with a counter can be used to map into even/odd rows. .filter with a counter could reasonably be used to skip every other value. Those cases exist with Array .map and .filter today, and being able to refactor to iterator helpers seems like a good thing. |
02:40 | <ljharb> | re strings, i guess we could have an AO like IsContainer or something, that returns true for Object, and eventually Record and Tuple, and require that in the helpers - and then Strings would never be iterated by default |
02:42 | <Justin Ridgewell> | Are tuples concat spreadable? |
02:42 | <Justin Ridgewell> | Apparently. |
02:45 | <rickbutton> | to confirm, whats the problem with iterable strings? that they are iterable at all, or that they don't iterate over the expected contents? |
02:45 | <HE Shi-Jun> | to confirm, whats the problem with iterable strings? that they are iterable at all, or that they don't iterate over the expected contents? |
02:45 | <rickbutton> | ooh |
02:46 | <bakkot> | https://www.xanthir.com/b4wJ1 |
02:46 | <rbuckton> | to confirm, whats the problem with iterable strings? that they are iterable at all, or that they don't iterate over the expected contents? Its bad for refactoring, and doesn't match user expectations.
|
02:46 | <rickbutton> | ah I see |
02:46 | <ljharb> | (iow we should have done String.prototype.codeUnits() and String.prototype.codePoints() and not had String.prototype[Symbol.iterator] at all) |
02:47 | <rickbutton> | ^ was just going to saythat |
02:47 | <rickbutton> | but alas |
02:47 | <HE Shi-Jun> | (iow we should have done codeUnits and codePoints now? |
02:47 | <ljharb> | absolutely, we just need a proposal and consensus (so, easy, right?) we wouldn't ever be able to unbreak strings tho :-( |
02:48 | <rbuckton> | How about .graphemes() ? |
02:48 | <ljharb> | yes please, altho then you'll be pointed to Intl.Segmenter |
02:48 | <HE Shi-Jun> | How about |
02:48 | <rickbutton> | delete String.prototype[Symbol.iterator] ez |
02:49 | <Richard Gibson> | and for good reason—grapheme cluster segmentation is locale-sensitive |
02:50 | <HE Shi-Jun> | Swift use locale-independent grapheme cluster (I don't remember the correct term), but may have some issues (I don't fully know). |
02:50 | <ljharb> | i'm mad at unicode, or maybe just all human beings, for making graphemes differ based on locale |
02:51 | <jschoi> | absolutely, we just need a proposal and consensus (so, easy, right?) we wouldn't ever be able to unbreak strings tho :-( .codePoints proposal really get much traction, or would it get too much pushback that We Already Have the Default String Iterator? |
02:51 | <HE Shi-Jun> | Just like JS have compatible requirements, unicode also, so .... |
02:51 | <ljharb> | [Symbol.iterator]() is utterly unergonomic tho |
02:51 | <HE Shi-Jun> | Array.values() vs Array[Symbol.iterator] 😅 |
02:54 | <rbuckton> | I don't think you can safely interleave next() and return() because of finally since that would put your source in a very weird state (pre-emptying the current await that might be in a try..catch..finally , etc.) |
02:55 | <bakkot> | with an actual generator that's definitely true |
02:55 | <bakkot> | but generators have an internal queue of those calls, so no problem there |
02:55 | <Anthony Bullard> | Michael Ficarra: Could you craft a real-life code example of a usecase for interleave next/return |
02:55 | <Anthony Bullard> | ? |
02:56 | <jschoi> | Array.values() vs .codePoints() proposal would be bundled with code-unit iterator(s?) and make the point that “we should encourage developers to use for (p of str.codePoints()) rather than for (p of str) as much as possible”. |
02:56 | <bakkot> | we should not encourage developers to do that |
02:56 | <bakkot> | for (p of str) is fine |
02:56 | <bakkot> | no objections to having a codePoints helper though |
02:57 | <Michael Ficarra> | msaboff: I just keep delegates.txt open in another tab when I am taking notes |
02:57 | <nicolo-ribaudo> | We should all put our abbreviation in the jitsi display name |
02:57 | <jschoi> | |
02:57 | <HE Shi-Jun> | |
02:57 | <bakkot> | jschoi: I agree with that thing but that ship has sailed |
02:58 | <bakkot> | strings are iterable, we can't take that back |
02:58 | <Ashley Claymore> | Symbol.iteratorV2 but don't put it on string.prototype (sorry tdz post) |
02:58 | <rbuckton> | I'd rather see for (p of str.codePoints()) because its more intentional. I've never been a fan of the disparity between str[i] and str[Symbol.iterator]() . |
02:59 | <jschoi> | The default string iterator can’t be made illegal, but developer guidance about it can change, right? Not that I feel that strongly one way or the other about what we should do about the situation myself… |
02:59 | <HE Shi-Jun> | strings are iterable, we can't take that back |
02:59 | <bakkot> | I don't think developer guidance helps with the actual problems in that essay |
02:59 | <jschoi> | Fair enough. |
03:00 | <bakkot> | I guess it helps with the "no correct way to iterate a string" thing |
03:00 | <bakkot> | but not the "infinite descent" thing, or the "accidentally passing it to something like the Set constructor" thing |
03:00 | <HE Shi-Jun> | TS (or other type checker) can warn that (theoretically) |
03:01 | <bakkot> | it can already warn about passing a string where an iterable is expected, though |
03:01 | <bakkot> | can and possibly should |
03:01 | <bakkot> | don't need new developer guidance for that |
03:02 | <bakkot> | (maybe a job for tslint rather than TS proper) |
03:02 | <jschoi> | it can already warn about passing a string where an iterable is expected, though .codePoints would be nice for the compiler as well as human readers, right? That’s kind of a case where developers “should” use .codePoints instead of the default iterator. |
03:02 | <rbuckton> | Unfortunately, TS doesn't really have "warnings", per se. Every diagnostic has the same level. |
03:03 | <bakkot> | every diagnostic is a warning, that's what // ts-expect-error is for :P |
03:03 | <bakkot> | jschoi: yeah that's fair |
03:03 | <Ashley Claymore> | We should all put our abbreviation in the jitsi display name |
03:03 | <rbuckton> | I'd much rather pass a str.codePoints() into something that expects an iterable when I know I want the code points, vs [...str] (both because the former is clearer and the latter is eager) |
03:04 | <jschoi> | …Though come to think of it, we probably should call it something like .byCodePoints() or .codePointStrings() or something. Because the language already uses “code points” to refer to integers: String.codePointAt returns integers. |
03:04 | <Anthony Bullard> | +1 (and Jitsi should make it even clearer who is currently talking even if someone else is screen sharing) |
03:04 | <rbuckton> | (and yes, you could do str[Symbol.iterator]() to not be eager). |
03:04 | <Anthony Bullard> | I now put jitsi in full screen in tile mode on my left monitor, and the etherpad on the right monitor |
03:05 | <bakkot> | …Though come to think of it, we probably should call it something like |
03:08 | <Anthony Bullard> | Is it possible for us to have some sort of coordination during note taking, or has something like that been attempted? Three people live editing the transcription gets very frustrating |
03:10 | <Anthony Bullard> | And does the transcription bot just get a single stream of audio, or would it have a way of detecting the speaker and including those annotations? |
03:10 | <bakkot> | just a single stream of audio |
03:10 | <rbuckton> | Kinda wish we had a char -like concept in JS (at least, the C# version that is always a wide char) that wasn't just Number /String |
03:11 | <Anthony Bullard> | Too bad we ran out of quotes to use for it |
03:11 | <bakkot> | it is in principle possible to write something which talks to the Jitsi API to detect the current speaker but that would be a lot of work |
03:11 | <bakkot> | PRs welcome though https://github.com/bakkot/transcribe-to-gdocs |
03:11 | <Michael Ficarra> | I think the latest version of Jitsi already has this though, right? |
03:12 | <bakkot> | has what? |
03:12 | <bakkot> | has live transcriptions output to google docs? no it does not |
03:12 | <Michael Ficarra> | not to gdocs, to some sort of log, I can look for the PR later |
03:12 | <HE Shi-Jun> | Kinda wish we had a char ? |
03:13 | <Anthony Bullard> | Note sure we have good use case of |
03:15 | <jschoi> | It’d have been better for everyone if it was never named “char” in Java but rather “utf16unit”. :’) |
03:16 | <Anthony Bullard> | Yeah, char has connotations of ASCII, or at least 8-bit character |
03:17 | <Anthony Bullard> | But maybe not to your workaday JS developer |
03:19 | <jschoi> | It’s my opinion that, because “character” has so many different meanings (8/16/32-bit code units, code points, combining character clusters, grapheme clusters), it’s too ambiguous and should generally be banned from technical documentation and APIs and replaced by more specific phrases. But that’s me…… |
03:19 | <jschoi> | The word is a real source of confusion though; there’s a reason why it takes up basically a whole section of the Unicode FAQ. |
03:19 | <Anthony Bullard> | At this point in time, that's probably correct |
03:20 | <bakkot> | "character" in the JS spec, used in the regex processing part, means either code point or code unit depending on whether the current regex is /u or not |
03:21 | <bakkot> | that's a fun one |
03:24 | <Anthony Bullard> | oof |
03:25 | <Anthony Bullard> | It seems like Strings, when looked from the modern landscape are at least as complex as time. |
03:25 | <bakkot> | mmmmmmm no time seems harder still |
03:25 | <Anthony Bullard> | In terms of representation, manipulation, and inspection |
03:26 | <Anthony Bullard> | I probably need to sit down and write that thought out to sanity check myself |
03:28 | <Anthony Bullard> | I'm sure the Temporal champions would very quickly disabuse me of that proposition |
03:28 | <jschoi> | Strings are hard if only because text is hard, and text is hard because human writing systems are nuts. Then again, time is nuts too, so. |
03:29 | <Anthony Bullard> | There are a lot of similar problems there actually |
03:29 | <Anthony Bullard> | For much of the same reasons |
03:29 | <rbuckton> | At least strings in JS support operators. Temporal, unfortunately, does not :/ |
03:30 | <HE Shi-Jun> | It’s my opinion that, because “character” has so many different meanings (8/16/32-bit code units, code points, combining character clusters, grapheme clusters), it’s too ambiguous and should generally be banned from technical documentation and APIs and replaced by more specific phrases. But that’s me…… |
03:30 | <bakkot> | strings probably shouldn't've supported operators |
03:30 | <bakkot> | lexicographic ordering is locale-dependent |
03:30 | <bakkot> | concatenation is crazy with combining characters |
03:31 | <bakkot> | === is crazy with canonicalization and normalization |
03:31 | <Anthony Bullard> | maybe we could use "rune" (rust, go use that term?) |
03:31 | <HE Shi-Jun> | strings probably shouldn't've supported operators |
03:31 | <Kris Kowal> | A rune by any other name would yet be a number. |
03:32 | <Kris Kowal> | I hesitate to mention that Unicode does have more quote characters. |
03:32 | <bakkot> | aw yeah, Left-Pointing Double Angle Quotation Mark |
03:33 | <Anthony Bullard> | I hesitate to mention that Unicode does have more quote characters. |
03:33 | <Kris Kowal> | There was a lovely hack for "generics" in Go that employed a source-to-source transform and aboriginal brackets. |
03:35 | <Anthony Bullard> | I was wrong, Elixir uses the pattern ?<character literal> to get the code point |
03:35 | <jschoi> | There’s a fundamental, philosophical question here: When two types have an equivalence relation, when should they be unified? In this case, should code units be unified or separated from integers? But it’s a far more general problem than that. |
03:35 | <Kris Kowal> | (My opinion is that number is a fine representation for char/rune in a language with a unified number type. It’s consistent with the rustic aesthetic.) |
03:35 | <Anthony Bullard> | Which might solve some usecases for the desire for characters, but not enough |
03:36 | <Anthony Bullard> | I think what people want is to type something like ?😀 and get the code point(s) |
03:37 | <Anthony Bullard> | But there is probably a lot wrong with that idea |
03:37 | <Anthony Bullard> | I probably should stop prognosticating on such matters at this hour |
03:38 | <Kris Kowal> | I can tell you what I want is to be able to query the kernel terminal discipline for how many columns a string is going to render into in the connected tty without having to pre-render them all, but I also know I’m not going to get that ever. |
03:39 | <Kris Kowal> | Some would call my motivating use case esoteric: emoji + tty + roguelike |
03:41 | <Kris Kowal> | But as bakkot mentioned, string concatenation only hints at the problem. If a streaming an emoji with combining characters is interrupted by a write flush, the tty is compelled to render the incomplete sequence, followed by the remaining incomplete sequence, and the outcome is not consistent. |
03:41 | <jschoi> | …Have any text-based roguelikes attempted to use all of (printable) Unicode for its symbols, using a pan-Unicode bitmap font like GNU Unifont? But wrong channel, I guess. |
03:41 | <Anthony Bullard> | That is why emoji are largely not fit for tty |
03:42 | <Kris Kowal> | Yes, and on the web, you’re not going to know enough about your string until you run it by font metrics. |
03:42 | <Anthony Bullard> | But much more essential characters face the same problems I'm sure (CJK, Devanagari?) |
03:43 | <Kris Kowal> | Hangul, for certain. |
03:43 | <Kris Kowal> | And of course the hypothetical code page of combining tengwar and tehtar. |
03:43 | <Anthony Bullard> | I never used Hangul in a tty scenario |
03:43 | <jschoi> | Emoji display is different than emoji characters; you don’t necessarily need combining characters or variation sequences just to have the characters themselves printed on a streaming TTY, as long as the TTY supports SMP characters. |
03:44 | <jschoi> | I…think… |
03:44 | <Kris Kowal> | Hangul evidently have both combining and non-combining glyphs depending on when they entered unicode. |
03:44 | <Anthony Bullard> | That is surprising, Hangul is a very simple, small script - I wonder how they would have entered unicode at different times? |
03:44 | <jschoi> | As far as I know, modern Hangul entered Unicode all at once, both composed and decomposed. |
03:44 | <Anthony Bullard> | Maybe historical glyphs? |
03:45 | <jschoi> | Otherwise, they wouldn’t’ve been able to create the special character-name rules for the composed characters. |
03:45 | <Anthony Bullard> | There are I think 3 historical glyphs that are obsolete |
03:45 | <Anthony Bullard> | I haven't spoken or written Korean in any meaningful respect in 17 years, so that's probably wrong |
03:47 | <jschoi> | …Yeah, the Hangul Syllables block was entirely added in Unicode 2.0 / 1996. Though it’s all modern of course. |
03:47 | <rkirsling> | then again some syllables could be viewed as hypothetical |
03:47 | <Anthony Bullard> | then again some syllables could be viewed as hypothetical |
03:51 | <jschoi> | For what it’s worth, as far as I know, every syllable combination encoded in Hangul Syllables is in actual use. I do not have data to back this up. |
03:51 | <Anthony Bullard> | 7 obsolete Hangul letters, 5 simple characters, 2 obsolete ssang(double) characters. Would love to hear what ssang-hieut sounded like... |
03:53 | <Anthony Bullard> | then again some syllables could be viewed as hypothetical |
03:55 | <Anthony Bullard> | And of course the hypothetical code page of combining tengwar and tehtar. |
03:56 | <Kris Kowal> | Hopefully not on the same screen as emoji... |
03:56 | <jschoi> | Code blocks (and code-point order) were never meant to be meaningful for users; they’re artifacts of encoding history and optimization. This is what Unicode says, but I think Unicode could do a better job of showing this. Maybe by presenting human-user-friendly pages of writing-system repertoires… |
03:57 | <rkirsling> | I mean, the ones that exist need to exist by virtue of being valid combinations, but |
03:57 | <Kris Kowal> |
|
03:58 | <ryzokuken> | can folks hear me? |
03:58 | <bakkot> | ryzokuken if you just said "jschoi would you mind sharing your screen", yes |
03:58 | <bakkot> | otherwise no |
03:58 | <ryzokuken> | ah, yes |
03:58 | <ryzokuken> | I did 🙈 |
03:58 | <rkirsling> | kind of unclear whether these would all see use: 훪 훫 훬 훭 훮 훯 ...is why I said hypothetical |
03:59 | <rkirsling> | if it were just combining parts, then those would be possible but you wouldn't necessarily dwell on 'em |
04:00 | <jschoi> | I’m sorry, give me a minute. Technical difficulties. |
04:02 | <bakkot> | Michael Ficarra: do you want to put conclusions from previous presentation in the notes? |
04:03 | <jschoi> | Can anyone hear me? |
04:04 | <jschoi> | (I’m a little confused on whether I’m supposed to go up right now. I can’t hear anyone right now.) |
04:04 | <ryzokuken> | yes |
04:04 | <ryzokuken> | we're waiting for you |
04:04 | <ryzokuken> | did you try clearing browser cache? |
04:05 | <bakkot> | there's been some people speaking so if you can't hear it's on your end |
04:05 | <bakkot> | jitsi reset my audio out/in devices, which might be the issue? |
04:05 | <bakkot> | had to manually change it to the right one |
04:06 | <ljharb> | my ios app still has no audio (and apparently nobody could hear me speak either) so i can only get it to work on the web |
04:06 | <Kris Kowal> | you’re on! |
04:06 | <Kris Kowal> | i was also unable to get audio on ios |
04:20 | <ljharb> | nicolo-ribaudo: your audio is harshly loud, btw, not sure if that's something you can adjust update: it's good now! |
04:29 | <HE Shi-Jun> | what last question (capture) means? I suppose it should work like Array.from which have the third argument to provide this ? |
04:37 | <HE Shi-Jun> | oh, i c. it has been fixed minutes ago :) |
04:40 | <HE Shi-Jun> | has is ambiguous ( hasKey / hasValue ) 😂 |
04:40 | <Kris Kowal> | This is where we have Bradley’s conversation about covariant and contravariant sets. |
04:41 | <Kris Kowal> | Set.prototype.hasKey ~ CoSet.prototype.hasValue |
04:42 | <rbuckton> | Would the MVP for this be to only allow union/intersection with a Set (i.e., via brand check)? |
04:43 | <Michael Ficarra> | rbuckton: no, because the interface we use is observable and can't change in the future |
04:44 | <rbuckton> | I'm not clear on why this can't change? Or is it because Set is subclassable? |
04:44 | <Michael Ficarra> | you could either subclass Set or add Set.prototype properties to observe the API we're consuming (or lack of it) |
04:45 | <Michael Ficarra> | it would force our hand to use new symbols in the future I guess |
04:45 | <rbuckton> | The point of throwing an error for anything other than a branded Set would be to allow us to loosen that restriction in the future. |
04:47 | <Kris Kowal> | map.keySet() , map.valueSet() façades? |
04:47 | <Michael Ficarra> | rbuckton: no, that still doesn't work |
04:48 | <Michael Ficarra> | a set subclass could be passed today with an overridden has that side effects, which wouldn't be called if you touched the argument's slots instead of using the public API |
04:48 | <Michael Ficarra> | it would then break (start side effecting) if we began using the string-based API of the argument |
04:48 | <Michael Ficarra> | this design would force us to either continue touching internal slots (bad) or use a Symbol-based API |
04:49 | <ptomato> | I agree with Kevin that a good design principle is that wrong things should be obviously wrong, if possible |
04:49 | <ljharb> | hm, i think my queue item got skipped |
04:49 | <Michael Ficarra> | ljharb: I don't think so, I see it |
04:49 | <ljharb> | oh weird, i don't. i'll refresh |
04:49 | <ryzokuken> | ljharb: was there another one? |
04:50 | <ljharb> | nah ok, it's there, tcq just glitched i guess (i just deleted it, so now it's supposed to be gone) |
04:50 | <ryzokuken> | its glitching for me too, so I thought I skipped it on accident 😓 |
04:50 | <Michael Ficarra> | consistency is hard |
04:51 | <ryzokuken> | now I don't see it either |
04:51 | <ryzokuken> | ljharb: can you add it again? I'll move it up |
04:51 | <ljharb> | i mean i deleted it on purpose :-) |
04:51 | <ryzokuken> | ah |
04:52 | <ryzokuken> | alright, I misunderstood |
04:52 | <Kris Kowal> | Petting a cat as if it were a dog works sometimes. |
05:02 | <rbuckton> | We could also have something like this:
Where |
05:04 | <Kris Kowal> | Aye, and Map.prototype.keySet and Map.prototype.valueSet that provide façades with varying has behavior. |
05:04 | <Kris Kowal> | Well, valueSet oddly not valuable. |
05:05 | <Kris Kowal> | Sec |
05:05 | <rbuckton> | Aye, and new Set(map.keys()) , and new Set(map.values()) |
05:06 | <Kris Kowal> | I see you’re implying Map.prototype[Symbol.asSet] that produces a façade that behaves consistently with the Set protocol. That’s reasonable. |
05:06 | <Kris Kowal> | new Set(map.keys()) is comparably expensive. |
05:07 | <Michael Ficarra> | rbuckton: yes that is also a reasonable option |
05:08 | <Jack Works> | is it possible to, make only two native, unmodified sets to read internal slots (so they're in the fast path) |
05:08 | <Jack Works> | and all other cases go in the slow but predictable path |
05:09 | <Michael Ficarra> | some day! |
05:11 | <HE Shi-Jun> | oh weird, i don't. i'll refresh |
05:12 | <snek> | in elixir you can do some_set |> MapSet.union(%MapSet{map: your_map}) |
05:13 | <HE Shi-Jun> | off-topic, I hope the queue could have emoji like 👍️ on each item, so I can just show my support without add another +1. |
05:14 | <Michael Ficarra> | I feel like we are struggling to defend indefensible positions at this point. Who would actually want an array passed to set union/intersection to operate on its indices? |
05:15 | <ryzokuken> | off-topic, I hope the queue could have emoji like 👍️ on each item, so I can just show my support without add another +1. |
05:15 | <rbuckton> | I feel like we are struggling to defend indefensible positions at this point. Who would actually want an array passed to set union/intersection to operate on its indices? array.keys() . |
05:17 | <Michael Ficarra> | unfortunately it appears we do not yet have a shared goal here, which is making it impossible to debate solutions |
05:19 | <Michael Ficarra> | well put, ptomato |
05:20 | <HE Shi-Jun> | Justin Ridgewell: not only keys/values, might also entries 😅 |
05:21 | <HE Shi-Jun> | I believe TS doesn't solve IndexedSet issue? |
05:24 | <rbuckton> | Or do the slow thing and have .intersection do new Set(other) and always operate on sets. :/ |
05:24 | <Justin Ridgewell> | Have union check for size ? |
05:25 | <snek> | hot take: don't sort NaN |
05:26 | <Kris Kowal> | see also: don’t pet cats |
05:26 | <Kris Kowal> | see also: don’t use maps as sets |
05:28 | <Kris Kowal> | (Ron: I see you’re not in the queue for asSet. I’d like to hear that argument.) |
05:28 | <Kris Kowal> | (Alas, would have liked to.) |
05:29 | <Michael Ficarra> | uuhh I do not recall intending to have Set/Map APIs overlap so they're interoperable |
05:30 | <Michael Ficarra> | can anyone definitively refute that? |
05:31 | <rbuckton> | I don't recall that being an intent, but do recall having a consistent API was intentional. |
05:31 | <Michael Ficarra> | apparently Waldemar recalls such an intent |
05:32 | <ljharb> | and has argued as such with https://github.com/tc39/proposal-collection-normalization |
05:32 | <ljharb> | (imo related to the conflicting but dually true mental models of Sets only having keys, vs only having values) |
05:34 | <Michael Ficarra> | lmao thenables is a perfect example of getting this design wrong |
05:35 | <Michael Ficarra> | I don't understand how we can be so far apart on this right now |
05:39 | <shu> | i think if there were more affordances for symbol-based names, we'd be back at square one |
05:39 | <Bradford Smith> | rbuckton: +1 to your suggestion of obj[Symbol.asSet]() return an object implementing whatever we decide to define the API of "set" to be |
05:40 | <Bradford Smith> | I don't love 'keys()` as the API name of the "iterate over the contents of a set" method. This discussion is an example of why it's not great. |
05:40 | <Michael Ficarra> | Bradford Smith: the downside of something like that is that it's a bit broad; you can't rely on finer-grained subsets of capabilties |
05:40 | <Michael Ficarra> | like something could have some properties of a set and not others |
05:41 | <Michael Ficarra> | but we're forcing ourselves to group them all together with that kind of design |
05:41 | <snek> | i think subsets of random classes is like |
05:41 | <snek> | way too big of a problem |
05:41 | <snek> | i like asSet |
05:41 | <shu> | i think i am also not a fan of having a public string-based API and a Symbol-based API where there's overlap in the semantics |
05:43 | <Michael Ficarra> | shu: Array.prototype.values? |
05:43 | <shu> | Michael Ficarra: i don't follow |
05:44 | <snek> | values duplicates [Symbol.iterator] on array |
05:44 | <Michael Ficarra> | shu: there's a bunch of string-named methods that are equivalent to a Symbol-named one (in this case Symbol.iterator) |
05:44 | <snek> | but i think that is OK |
05:44 | <shu> | that's complete overlap |
05:44 | <shu> | that seems fine to me |
05:44 | <Bradford Smith> | shu: I don't interpret rbuckton's suggestion as having a Symbol-based API. It could just as easily be that we decide that Set.prototype.intersection requires its argument to have an asSet() method, and that method must return an object that is iterable and has has() and size . |
05:44 | <waldemar> | NaN is not the only value for which the "return a-b" sort comparator is inconsistent. |
05:44 | <Michael Ficarra> | shu: are we talking about partial overlap? |
05:44 | <shu> | Bradford Smith: i wasn't responding to rbuckton's but to kevin's suggestion of @@SetHas and @@SetSize |
05:45 | <snek> | i am now wondering how long until this proposal morphs into the first class protocols proposal |
05:47 | <shu> | Michael Ficarra: yeah the partial overlap is where a lot of my dislike comes from. concretely, today, there's the public string-based API for Maps that's, like, Set-like enough because we don't have additional algorithmic constraints stipulated by union and intersect. kevin's proposal for the symbol API is now like, "actually, even more set-like, in a different namespace, with this small delta in guarantees" |
05:47 | <rbuckton> | Symbol.queryInterface when? |
05:47 | <Michael Ficarra> | shu: ah gotcha |
05:48 | <shu> | that's what i meant originally by "ad hoc protocol" |
05:48 | <shu> | or at least, the ad hoc-ness |
05:49 | <Michael Ficarra> | any kind of virtual dispatch always runs into this problem: what constraints does this method have that aren't reflected in its type? |
05:49 | <shu> | no, that's actually not what i'm saying |
05:50 | <shu> | but it's late, i don't think it's too important for me to be clear here for the proposal |
05:51 | <rbuckton> | set.intersection(new Set(array)) , done |
05:51 | <snek> | i don't expect this at all |
05:52 | <rbuckton> | I don't expect this either. Maybe if the only requirement was that it was iterable, but not if we want intersection to be speedy. |
05:52 | <Justin Ridgewell> | ljharb: I dont' think that reasoning holds, because new Set(map) is useless |
05:52 | <Justin Ridgewell> | Just because something can create a set with elements doesn't mean it's appropriate for functions that receive sets. |
05:52 | <ljharb> | that's not the reasoning i used |
05:52 | <ljharb> | new Set(map) doesn't make a set that conceptually matches the input |
05:53 | <ljharb> | new Set(array) however does |
05:53 | <shu> | Michael Ficarra: but one last attempt: it's a public API evolution problem. if version 1 has one set of virtually dispatched methods, i think having version 2 where there's a new set of virtually dispatched methods where some of them conceptually overlap with the version 1 set of methods is Not Good |
05:54 | <rbuckton> | What if its: "If the argument is set-like use it like a set. If the argument is iterable, make a set from it and use that. Otherwise, throw"? |
05:59 | <Michael Ficarra> | rbuckton: and what makes something set-like? |
06:00 | <rbuckton> | Per the consensus, size (-ish), has() , and keys() I suppose. |
06:03 | <shu> | bakkot: you said you had wanted your proposal to be precedent setting. do you consider the result, which you disliked, to still be precedent setting (i.e. that we're sticking with naive string-named method duck typing)? |
06:04 | <Michael Ficarra> | I think the precedent-setting part was talking about where we put the symbols lol |
06:04 | <Michael Ficarra> | we didn't get that far |
06:04 | <shu> | that's what i'm asking |
06:04 | <shu> | do you consider this signal against protocols |
06:04 | <shu> | or do you consider it a one-off decision that they were a poor fit here |
06:04 | <bakkot> | well |
06:04 | <Michael Ficarra> | also with all the special casing we discussed, it would be hard to see this as precedent setting |
06:04 | <bakkot> | I want to not consider it precedent because I think it's a mistake |
06:05 | <shu> | then i look forward to the counterarguments for when protocols come back :) |
06:05 | <shu> | the arguments i heard from the other side seemed fairly general |
06:05 | <bakkot> | and intend to argue against using this design in the future in all the situations I'd argue against perpetuating any other historical mistake |
06:05 | <Michael Ficarra> | shu: no, the first-class protocols is primarily a facility for users to more easily create and consume protocols like the ones that are (sometimes) used by built-ins and syntax |
06:06 | <Michael Ficarra> | it is still good for users to do that |
06:06 | <bakkot> | yeah Symbol.iterator is still enough precedent for protocols |
06:06 | <bakkot> | Symbol.iterator was obviously good, I hope we are agreed? |
06:06 | <bakkot> | though I guess I should have asked waldemar or mark their opinions on it |
06:06 | <shu> | Michael Ficarra: okay, even if we do not apply it to builtins? |
06:06 | <Michael Ficarra> | even if we inconsistently apply it with built-ins, yes |
06:07 | <shu> | i see |
06:07 | <Michael Ficarra> | it's just as useful for building a healthy ecosystem |
06:07 | <shu> | i prefer nominal personally |
06:07 | <shu> | i agree with the need to signal a promise of conformance to some contract |
06:08 | <Michael Ficarra> | bakkot: I don't know what we agree on anymore |
06:11 | <shu> | i guess ron's idea is pretty much nominal |
06:11 | <bakkot> | we discussed this some at the end. I don't hate that option, but I do dislike that it has subtle performance characteristics; I would prefer to make the performance characteristics more explicit by making the user do the iteration of the iterable themselves |
06:12 | <shu> | i agree with that about explicit performance characteristics, unsurprisingly |
06:12 | <shu> | if we have nominal interface checking might as well just make it throw if it doesn't have it |
06:13 | <shu> | yes it's not JS-y but neither is having strong built-in behavior contracts? |
06:15 | <bakkot> | the "eagerly coerce values" behavior is one of the largest original sins of JS |
06:15 | <bakkot> | glad iterator helpers is at least starting to move away from that by guarding against NaN in take instead of just coercing it to zero, of all things, like slice does |
06:16 | <ljharb> | i'd expect erights would say the same about the "override mistake" and hidden intrinsics needing to be fixed instead of cargoculted forever |
06:16 | <Michael Ficarra> | bakkot: 🤫 you'll expose us |
06:16 | <bakkot> | override mistake is an original sin but nowhere near as large of one |
06:17 | <ljharb> | everyone has a sacred anticow they want to see slaughtered, and if we're condemned to repeat JS's mistakes forever, nobody'll be happy |
06:17 | <ljharb> | it makes much more sense to me to ack JS's mistakes and fix them wherever we feel we can get away with it |
06:17 | <shu> | override mistake is just a case of the world model implicit in the Old Scripture being lost |
06:17 | <shu> | i.e. prototypes being actually prototypical and designed to be cloned to make new instances |
06:18 | <shu> | instead of just being delegates |
06:20 | <nicolo-ribaudo> | The idea was that "new Foo" is "Foo.call({ ...Foo.prototype })"? |
06:22 | <shu> | yes |
06:22 | <shu> | https://en.wikipedia.org/wiki/Self_(programming_language)#:~:text=Instead%20of%20having,as%20prototypes. |
06:22 | <bakkot> | i agree with the need to signal a promise of conformance to some contract |
06:22 | <bakkot> | that doesn't signal conformance at all |
06:22 | <bakkot> | or are you agreeing in general but not this specific case |
06:23 | <shu> | i agree in general not with symbol-based methods |
06:23 | <shu> | i also think the current pervasive string-named duck typing way does signal conformance, in a really shitty way |
06:24 | <shu> | time for sleep |
07:07 | <HE Shi-Jun> | i'd expect erights would say the same about the "override mistake" and hidden intrinsics needing to be fixed instead of cargoculted forever |
07:14 | <bakkot> | the thing where 'use strict'; let x = { __proto__: Object.freeze({ prop: 0 }) }; x.prop = 1; throws instead of assigning to a property on x shadowing the thing on the prototype |
07:15 | <ljharb> | iirc that if an inherited property is nonwritable, and you try to write to it, it throws |
07:15 | <ljharb> | is it proven to be web incompatible to change that? I’m assume it has |
07:17 | <bakkot> | in TDZ a while back Rob Palmer said
|
07:17 | <bakkot> | so presumably yes? |
07:44 | <littledan> | Btw is the bot magically doing better this month or do we still want a stenographer? |
08:23 | <nicolo-ribaudo> | I took notes for a few hours, and I still want a stenographer |
08:41 | <littledan> | Aside from the delegate naming issue, are there bot technologies that we should be adopting and haven’t done, that might improve the core accuracy of transcription ? |
08:49 | <nicolo-ribaudo> | The main problem I continue having is that the speech-to-text API we use doesn't work well if your English doesn't have a "common" accent, making it very hard to edit its transcription of non-native speakers (me included) |
08:50 | <nicolo-ribaudo> | But I don't think we can fix it in the bot |
08:59 | <Ashley Claymore> | For me it’s also that the bot is slower than the stenographer. For me to be of any use taking notes I have to add a 5-10 second delay to my audio. Which further means I can’t interact with what is happening. |
11:35 | <Anthony Bullard> | For me it’s also that the bot is slower than the stenographer. For me to be of any use taking notes I have to add a 5-10 second delay to my audio. Which further means I can’t interact with what is happening. |
11:53 | <littledan> | OK, thanks for the feedback, I will keep going with the request to Ecma. |
12:31 | <HE Shi-Jun> | the thing where |
12:35 | <HE Shi-Jun> | is it proven to be web incompatible to change that? I’m assume it has |
12:36 | <littledan> | yes, this decision was made in the ES5 era |
12:38 | <HE Shi-Jun> |
|
12:39 | <littledan> | I guess that was a heavily qualified statement; other mistakes are sort of clearly not on a path to be fixed |
12:39 | <littledan> | (like, I'd love it if we could fix the mistake of typecasts all over the place...) |
12:39 | <littledan> | (and undefined casting to NaN in particular! that is literally the worst) |
12:42 | <Rob Palmer> | As the SES folk will tell you, the override mistake prevents simplistic freezing of all the primordials. Freezing the global object helps ensure robustness and opens up efficiencies for running semi-isolated tasks in the same runtime enviromnment. Whether this is the "biggest" mistake depends on your own personal value judgements. I have already made my peace with other "mistakes" like typeof null. |
14:43 | <Jack Works> | For example |
14:44 | <Jack Works> | After you freeze the Function.prototype, MyOldES5Class.toString = ... will be an error, which is very common in the ES5 era |
14:45 | <Jack Works> | If Function.prototype is not frozen, doing this will not change F.prototype.toString, but define a new own property on MyOldES5Class |
15:14 | <HE Shi-Jun> | But u still can use Object.defineProperty to add toString ? |
15:15 | <ljharb> | you can, yes - but most code never uses that |
15:16 | <HE Shi-Jun> | Yeah, it requires u to change code, but if someone want to use SES, they very likely need to change some codes. |
15:39 | <Jack Works> | Unfortunately, it's not "change some code" most of the time, it's "patch node_modules". |