10:04 | <Luca Casonato> | what are people's opinons on changing the Map and Set constructor to not call Symbol.iterator on the passed value if the passed value brand checks as a Map/Set? So new Map(new Map()) would not call Map.prototype[Symbol.iterator] anymore |
10:44 | <Ashley Claymore> | We didn't do this for `Set.prototype.union` and co |
10:51 | <Ashley Claymore> | Do any engines have a faster path for this already, the value is a real Map and the iterator hasn't been modified |
10:54 | <Ashley Claymore> | I am interested how much benefit there would be if we can modify array destructuring to avoid the iterator when destructuring an array |
12:45 | <yulia> | Is the draft schedule up yet? |
13:48 | <Chris de Almeida> | nearly |
14:13 | <Chris de Almeida> | draft schedule now available via reflector issue: https://github.com/tc39/Reflector/issues/558 |
15:20 | <Luca Casonato> | I am interested how much benefit there would be if we can modify array destructuring to avoid the iterator when destructuring an array |
15:22 | <ljharb> | engines can already do that unobservably when they know the map/set isn't modified |
15:38 | <snek> | I don't think any engine does it for these, it's very annoying to track |
15:38 | <snek> | having the spec change would definitely help |
15:41 | <mgaudet> | Agreed with snek; while heroics are possible and sometimes happen, any place we can specify that no heroics are needed is appreciated |
16:12 | <iain> | We actually already optimize this path |
16:13 | <iain> | Although it would be nice if we didn't have to do all the careful plumbing to make sure it's a valid transformation |
16:14 | <ljharb> | (tbc i'm fully on board with having explicit fast paths for things that pass brand-checks) |
16:25 | <bakkot> | at least the map iterator isn't side-effecting |
16:25 | <bakkot> | array iteration is probably the most common case and the iterator has side effects all over the place |
16:36 | <Ashley Claymore> | Array iterator side-effecting in that it triggers MOP methods? |
16:40 | <bakkot> | sure and also getters |
16:42 | <bakkot> | also this is a good place for me to beat my drum of "iterating built ins does not need allocations" https://docs.google.com/document/d/1M5S-u3N3vQkVBGFCoaYt_ABPGl0EW16QQrvDBaY2FiE/edit |
19:11 | <shu> | Rob Palmer Chris de Almeida please accommodate https://github.com/tc39/agendas/pull/1889 if possible. i know that AsyncContext is held up on web integration stuff, and Scott represents the web side of it for Chrome, so i think it's important to get his input during plenary |
19:13 | <shu> | could a chair please ping me if the constraint could (or not) be accommodated? |
19:13 | <shu> | (in case of not, would try to find a secondary) |
21:33 | <James M Snell> | Hey all... had some feedback come up with regards to Explicit Resource Management today that I wanted to surface and get some input on. The question specifically is, "I think explicit resource management is missing a really important feature: The ability to transfer ownership. I need a way to "release" a variable I declared with using, especially to return it." ... essentially treating the ERM/using as similar to an RAII that can be moved away.
|
21:35 | <James M Snell> | Unfortunately, since both are declared with using , both are going to be disposed when the function returns. The ask from the feedback is whether it would make sense to have some generalized "release" or "move" capability.. like return move bar , etc |
21:37 | <James M Snell> | obviously we can follow a pattern similar to DisposableStack and have the disposable object itself declare a move() method but that means allocating a new object or having to keep track of the moved state manually |
21:37 | <Duncan MacGregor> | So I think one of the good things about explicit resource management is its simplicity, there isn't much of an ownership or lifetime model to think about or to get wrong. |
21:38 | <James M Snell> | we can also null/undefined out the original decl and assign it to a regular scoped variable but that's also a bit wonky .... actually, nevermind, I don't think this works |
21:38 | <James M Snell> | 100% agree |
21:38 | <Duncan MacGregor> | I think I'd prefer seeing people declaring move() themselves rather than trying to design something in the language. |
21:39 | <Duncan MacGregor> | But now I'm curious if typescript could layer a full borrow checker on top and do this automatically. :-) |
21:52 | <James M Snell> | Making every disposable object declare a move() is a bit ... difficult. From the conversation I'm having in another channel on this, "It has to allocate a new instance of itself and move all the contents over to it. This is a lot of work to write for every type. And if anything else in the world holds a (presumably non-owning) reference to the object, those references are now invalid, so it might not even be possible to implement move() correctly, at least without adding a layer of indirection." |
22:16 | <Duncan MacGregor> | I think I need to sleep on it. I've started writing an reply about 5 times, and deleted them 5 times. My essential concern is that both the 'other non-owning references becoming invalid' and the return of the resource suggest that it is leaking in ways that probably aren't good for an explicit allocated and released resource (the former because we seem to have lost ownership during the method's lifetime, and the latter because we can't require the result is allocated to a variable declared with using ). |
22:19 | <James M Snell> | yeah, it's a tricky one |
22:21 | <James M Snell> | I prefer the simplicity of ERM as it is but compared to the typical RAII pattern in c++, etc it's a bit over simplified... and that's there the questions here are coming from. We have a code base that is quite heavy in RAII mechanisms and the c++ level with no equivalent at the JS level |
22:22 | <nicolo-ribaudo> | If we get Symbol.enter/exit, then you'd be able to declare a function `movable` that you'd use as `using x = movable(foo)` |
22:23 | <James M Snell> | Another example to stew on...
|
22:23 | <James M Snell> | Is there an open proposal for this? |
22:23 | <James M Snell> | and is it functions only? |
22:25 | <nicolo-ribaudo> | Actually maybe you don't need .enter? (Sorry my element client is refusing to format markdown) Instead of ``` using foo = getObj() ``` you can do ``` const foo = getObj(); using move = movable(foo) ... move() ``` Where movable returns a function move that returns foo and has its own dispose method forwarded to foo, deactivated by move. |
22:26 | <James M Snell> | ah, ok, so it's essentially like declaring a disposable boxed type similar to DisposableStack |
22:26 | <nicolo-ribaudo> | Is there an open proposal for this? |
22:26 | <nicolo-ribaudo> | It was also discussed in the context of async context, maybe @legendecas:matrix.org knows if we actually have a proposal |
22:27 | <James M Snell> | Interesting ok |
22:45 | <Chengzhong Wu> | https://github.com/tc39/proposal-using-enforcement for Symbol.enter |
23:32 | <bakkot> |
|
23:33 | <bakkot> |
|
23:33 | <bakkot> | this seems like it's fine to leave to userland |
23:33 | <bakkot> | it's a little boilerplate I guess |
23:49 | <Ashley Claymore> | Could make .move return a new movable in the same way DisposableStack.p.move returns a new Stack |
23:50 | <Ashley Claymore> | or maybe just return the resource after nulling it out |
23:52 | <Ashley Claymore> | though need to be careful moving in a _tearable_ hand over |
23:55 | <bakkot> | I think just returning the resource is better for the cases described above; presumably the caller is not expecting this wrapped thing and a priori there is no reason to expect them to want to move it again |
23:56 | <Ashley Claymore> | ``` return { p: moveable.move(), q: mightThrow() } ``` |
23:56 | <bakkot> | but good idea, returning the resource is a nice convenience, updated |
23:56 | <bakkot> | yeah it's easy to hold this wrong |
23:56 | <bakkot> | although this is also true of disposableStack.move() |
23:56 | <bakkot> | boundaries are always tricky |
23:56 | <bakkot> | not much to be done about that though without linear types |
23:57 | <Ashley Claymore> | Yeah, the point of stack.move is that it should be the very last expression |
23:57 | <Ashley Claymore> | to ensure the time to move has truly arrived |
23:58 | <shu> | if you return the resource and not a new movable, isn't that more like release() |
23:58 | <bakkot> | I guess but I liked the symmetry with disposableStack.move() |
23:58 | <shu> | but DS does return a new movable DS |
23:59 | <Ashley Claymore> | one difference is that the resource is itself a disposable, so it can be _used_ by the caller |