| 00:15 | <jschoi> | In the spec, is there a way to split an abstract List into a first element and another List of the other elements? | 
| 00:16 | <jschoi> | “Let «first, ...rest» be list”… | 
| 00:16 | <bakkot> | Nope | 
| 00:18 | <jschoi> | I’ll just say, “Let rest be the List of all elements of list except its first.” | 
| 00:20 | <bakkot> | If you own the list, you could just mutate it | 
| 00:21 | <jschoi> | Well, how would I express that in spec language? | 
| 00:21 | <jschoi> | It’d still be prose, right? | 
| 00:21 | <bakkot> | i. Let r be the first element of remaining. ii. Remove the first element from remaining. | 
| 00:21 | <jschoi> | Ah… | 
| 00:21 | <bakkot> | or | 
| 00:21 | <bakkot> | ii. Let kValue be the first element of values and remove that element from values. | 
| 00:21 | <jschoi> | Nice. Thank you! | 
| 00:22 | <bakkot> | Which thing are you writing that needs this? For bigint math I'd think you could just copy the Number ones | 
| 00:23 | <jschoi> | Math.hypot. KillingMath.bigHypotand merging its behavior intohypot. | 
| 00:23 | <jschoi> | Dispatching on the type of the first argument. | 
| 00:24 | <bakkot> | Math.hypot just iterates over the list; that seems better than splitting it | 
| 00:24 | <jschoi> | Well, it needs to coerce the rest of the arguments based on the first argument’s type, though. | 
| 00:28 | <jschoi> | https://github.com/js-choi/proposal-bigint-math/commit/b5ece4e1543c35375f13f02653c0a7119ed0c495 | 
| 00:29 | <bakkot> | Yeah but you don't need to take the tail of the list for that. I'd do something like etc | 
| 00:29 | <bakkot> | there's other ways you can write it but none of them obviously require you to construct the list-except-head | 
| 00:29 | <bakkot> | just to peek at the head to determine which coercer to use | 
| 00:31 | <jschoi> | Wouldn’t that cause an unnecessary call to ToBigInt or ToNumber for the first element? | 
| 00:31 | <bakkot> | Type() does not perform coercion, no | 
| 00:32 | <bakkot> | Though, I guess you probably want ToNumeric? | 
| 00:32 | <jschoi> | I mean ToBigInt, though. It’s calling ToBigInt on args[0] unnecessarily. | 
| 00:32 | <bakkot> | Yeah but that's unobservable | 
| 00:32 | <jschoi> | Oh, yeah, right, ugh, I forgot that I need to call ToNumeric on the first. | 
| 00:32 | <jschoi> | If we’re fine with unobservable redundant calls the spec, I can change it. | 
| 00:33 | <bakkot> | If that makes the algorithm easier to read, absolutely. | 
| 00:40 | <jschoi> | https://github.com/js-choi/proposal-bigint-math/commit/32152ba671e6b94e9912139db5b3a31e35ad9021 | 
| 00:40 | <jschoi> | Thanks for the help, bakkot! | 
| 00:42 | <jschoi> | …Though would it work with Math.hypot(Object(4n))? | 
| 00:42 | <jschoi> | Wouldn’t the Type(args[0]) return Object? | 
| 00:43 | <bakkot> | Right, that's why I suggested ToNumeric | 
| 00:43 | <jschoi> | Ah, ah. | 
| 00:45 | <jschoi> | So we’re fine with just replacing it with Type(ToNumeric(args[0])), because the extra coercion is invisible to the user. | 
| 00:45 | <bakkot> | Well, no, that ends up being visible, unfortunately | 
| 00:45 | <jschoi> | Ah… | 
| 00:46 | <bakkot> | So you do probably want to pop the list after all, I'm afraid | 
| 00:46 | <bakkot> | I hadn't thought through the fact that you'd want to ToNumeric before doing the Type | 
| 00:46 | <jschoi> | Thanks for the big help anyway, though. 👍️ | 
| 00:54 | <jschoi> | I wonder if ToPrimitive would work… | 
| 14:36 | <jschoi> | Could someone familiar with TypeScript type inference explain the problem being described in https://github.com/js-choi/proposal-hack-pipes/issues/18 ? I’m not sure why the type of userOption |> map(user => user.name)(^)cannot be inferred fromuserOptionandmap. | 
| 14:37 | <jschoi> | It’s just the same as map(user => user.name)(userOption), after all… | 
| 14:53 | <devsnek> | does anyone else keep getting surprised that optional chaining doesn't work with assignment | 
| 14:58 | <devsnek> | jschoi: i think they mean this https://www.typescriptlang.org/play?#code/GYVwdgxgLglg9mABAWwIYAcA8AVANIgVQD4AKYALkRIDdLsBKRAXiMPspNToG0BdRloT6IA3gChEkxACcAplBDSkNVABsQsgM49+zVtTUbNAOjToy9ANxiAvmLEQEmqIlTTpqAJ7NE3EQCNKAEYbXmszEk4BVlRjf3pOdy8rIA | 
| 14:58 | <devsnek> | i'd say that's just a dumb limitation of TS though, and you can manually annotate it, so i don't think it matters | 
| 15:04 | <jschoi> | Huh, I see. So the problem is that TypeScript cannot infer the type of even map(user => user.name)(userOption)…but, apparently, somehow it can infer the types inpipe(userOption, map(user => user.name))? 🤔 | 
| 15:05 | <devsnek> | yeah for some reason it doesn't unify the types in the former case | 
| 15:05 | <devsnek> | personally i'd say its probably just better for microsoft to fix that | 
| 15:08 | <jschoi> | I wonder if the TypeScript team has tried adding that inference but there’s a fundamental reason why they can’t, hmm. Anyways, thanks for help! | 
| 15:09 | <devsnek> | its weird cuz its not really even an inference, it's just unifying unknownand{b: number}:/ | 
| 15:16 | <jschoi> | jschoi: i think they mean this https://www.typescriptlang.org/play?#code/GYVwdgxgLglg9mABAWwIYAcA8AVANIgVQD4AKYALkRIDdLsBKRAXiMPspNToG0BdRloT6IA3gChEkxACcAplBDSkNVABsQsgM49+zVtTUbNAOjToy9ANxiAvmLEQEmqIlTTpqAJ7NE3EQCNKAEYbXmszEk4BVlRjf3pOdy8rIA | 
| 15:16 | <devsnek> | sure | 
| 15:19 | <jschoi> | Hm, maybe it’s a fundamental limitation of how TypeScript’s “type inference works left to right”. | 
| 15:21 | <jschoi> | Perhaps in map(user => user.name)(userOption)it can’t unify the types ofuseranduserOptionbecause…I don’t know, maybe it’s somehow unidirectional, it expects a type right away in that arrow function, and it eagerly throws an error right there before moving onto(userOption)? I wonder how solvable this would be for the TypeScript team, but having to usepipefunctions seems like a pretty brittle way to work around it. | 
| 15:41 | <jschoi> | Hmmm. https://github.com/microsoft/TypeScript/issues/15680 https://github.com/microsoft/TypeScript/issues/25826 https://github.com/microsoft/TypeScript/issues/30134 | 
| 17:09 | <TabAtkins> | Okay yeah sounds like it's just "we don't actually unify types, just do some inference tricks that fail in a lot of cases", but I'm still confused why pipe(val, map(user=>user.name))infers properly. | 
| 17:19 | <devsnek> | tsc continues to befuddle me | 
| 17:20 | <devsnek> | TabAtkins: it seems to just be the order in which the graph is visited, one of those issues has an example of changing the order of arguments breaking inference | 
| 17:23 | <TabAtkins> | Yeah, seems like there's some special-casing thrown around to address some cases. If this becomes a big issue, I suspect TypeScript can special-case "trailing (^)in a pipe body" and make it work like we'd expect, even without full inference. | 
| 17:33 | <devsnek> | apparently the swc person is writing a new typescript type checker | 
| 17:33 | <devsnek> | maybe it can handle this properly | 
| 18:56 | <bakkot> | we should make let { #x: a } = foowork, to meanlet a = foo.#x: y/n? | 
| 18:57 | <bakkot> | I have seeded the emoji reacts so you can more easily just click on the appropriate one to express your opinion | 
| 18:57 | <TabAtkins> | Tho let {#x} = foo;would still not work, right? | 
| 18:59 | <bakkot> | yup | 
| 18:59 | <bakkot> | or at least I am not proposing to allow it, and I think it should not work | 
| 19:47 | <Domenic> | My personal opinion is that renaming while destructuring is generally distasteful, so I am not voting. (I.e. I think let x = y.zis clearer thanlet { z: x } = y.) | 
| 19:53 | <devsnek> | i vote for whatever increases the number of productions in the spec |