00:20 | <TabAtkins> | Justin Ridgewell: Args being implicitly public works reasonably well in Python, imxp. (And you can now dictate that some args are positional-only and not available by name.) Or is the concern just that exposing arg name of existing functions, predating such a syntax, would be a problem? |
00:28 | <Justin Ridgewell> | My worry would be libraries who are unaware, but users who are. |
00:29 | <Justin Ridgewell> | JS devs don’t currently need to think about it, and so it’s normal for it to change without updating the major. |
00:30 | <Justin Ridgewell> | Additionally, what if the lib went through a minifier? What are the public names now? |
00:31 | <Justin Ridgewell> | And what will they be the next time it’s run though? |
00:32 | <Justin Ridgewell> | Terser uses char frequency to select mangled names. A completely unrelated code change in a string can cause the mangled name in a function to change. |
01:54 | <rbuckton> | I think if JS did add actual named parameters, you would have to opt-in somehow. |
02:42 | <rkirsling> | lol why do I even bother |
03:13 | <Justin Ridgewell> | lol why do I even bother |
03:13 | <rkirsling> | I spent hours thinking over why something was hard for me to understand and expressed it as clearly and concisely as I am capable. |
03:14 | <rkirsling> | in that sense it is subjective, but I feel like if I claimed "the sky is blue" at this point someone would "nuh uh" me |
03:18 | <Justin Ridgewell> | Which part do you think is being dismissed? |
03:19 | <Justin Ridgewell> | In a sense, I read your comment as a difficulty in translating the code into an English phrase. |
03:19 | <Justin Ridgewell> | And my thought to answer is "well this is how I would say it" |
03:20 | <rkirsling> | I didn't feel dismissed at all by your comment |
03:20 | <rkirsling> | I did want to clarify the notion of subject at that point but now it's just a chain of disagreeing with every presupposition I had |
03:21 | <rkirsling> | I didn't expect to convince anyone per se but I certainly hoped to clearly express where I was coming from |
03:21 | <rkirsling> | at this point I don't feel like I can speak again until somebody acknowledges what I was actually trying to say |
03:23 | <rkirsling> | and it's frustrating because I would expect that from the broader community, that's why I shy away from these threads so often, but |
03:31 | <rkirsling> | anyway I don't think it's a good place for round-and-round conversations |
03:34 | <Justin Ridgewell> | Rereading:
|
03:34 | <rkirsling> | otherwise one person spends hours trying to dot every i and cross every t while others spend two minutes regurgitating some entrenched view |
03:35 | <Justin Ridgewell> | If I understand right, you're treating log as something that would need to a bound to a context b ? |
03:35 | <Justin Ridgewell> | Which would always be on the RHS of the log expression |
03:36 | <Justin Ridgewell> | But this is directly at odds with what Jordan and I have expressed |
03:36 | <Justin Ridgewell> | Having to repeat the context on the right hand side is effectively the same ergonomics as hack pipe. |
03:37 | <Justin Ridgewell> | But it seems you'd be open to receiver :> fn() , and I think it's because the spaces make it appear fn is not a property lookup? |
03:37 | <rkirsling> | yeah so I explicitly said that I wasn't expecting people to like my suggestion that the operands be reversed, but I realized that that was the crux of why I find it so hard to read |
03:38 | <rkirsling> | yeah :> would seem okay at least for the .call case, though I wonder if it's separately problematic for the .bind case |
03:38 | <Justin Ridgewell> | But is it the spaces that make it more comfortable for you? |
03:39 | <rkirsling> | yeah because it's passing an argument |
03:40 | <rkirsling> | since JS is an imperative language, the "subject" of a function call is the engine, IMO 😅 |
03:40 | <rkirsling> | (or my computer. or me.) |
03:40 | <Justin Ridgewell> | Ok. |
03:40 | <Justin Ridgewell> | I could definitely see how a::b could be confused with namespace (effectively property) lookup. |
03:41 | <Justin Ridgewell> | And I don't think even spaces a :: b would help with that. |
03:42 | <Justin Ridgewell> | I'm fine with :> , it is a pipe behavior that I want https://github.com/tc39/proposal-bind-this/issues/10#issuecomment-936725043 |
03:42 | <Justin Ridgewell> | And it might be alright to have bound = receiver :> slice; |
03:42 | <Justin Ridgewell> | (which I don't want as much) |
03:42 | <rkirsling> | I'm fine with |
03:48 | <pokute> | So receiver.method() is then a bit weird when the combo of . and () makes () work differently when they're both present since the preceding . changes the "function" call. guess this is why . is bad to use with trailing whitespaces since it changes the following function call. I think ":> " with trailing whitespace might have the same problem - for a piece of code receiver :> func() the whitespace separates the receiver from the function call while I think it's a very important to link them strongly together. (I guess tacit function call application with arg |>> Math.round suffers a bit from the same problem.) |
03:50 | <Justin Ridgewell> | By changing it, do you mean that the a receiver is passed as this instead of nothing? |
03:51 | <Justin Ridgewell> | Doesn't having . and ( on the same line alleviate that? |
03:51 | <Justin Ridgewell> | Eg, we break up long chains:
|
03:52 | <pokute> | By changing it, do you mean that the a receiver is passed as |
03:55 | <pokute> | Of course, multi-line version would be usually formatted pretty straightforwardly, but a single-line .... && receiver :> freeFunctionLookalike() || ... might be misleading. |
03:57 | <Justin Ridgewell> | I mean, mixing binary operators is always confusing. 😛 |
03:58 | <Justin Ridgewell> | But yah, I have no idea where the expression nodes end in that example. |
03:59 | <pokute> | well, I didn't mean even that :-). I would rather see receiver :>freeFunctionLookalike() instead of receiver :> freeFunctionLookalike() for the same reason I would rather see receiver .freeFunctionLookalike() instead of receiver . freeFunctionLookalike() . |
04:01 | <rkirsling> | hmmm |
04:03 | <rkirsling> | I guess I'm really viewing it as the same as |> but |
04:04 | <pokute> | Hack pipeline has a bit of benefit where the "RHS" expression has an topic indicator that gives a hint that it's a part of a bigger expression. |
04:04 | <rkirsling> | that is true |
04:05 | <pokute> | Tacit function application or F# pipelines don't have such a hint always. |
04:09 | <pokute> | For these kind of issues, It's about even better to write some half-page example code where the point of interest snippet is embedded in - not too obfuscated but not too separated either. When we're having it as a topic of discussion, we automatically focus our attention for it and can't really evaluate how it looks around other code. |
04:09 | <rkirsling> | I guess in the case of :> we don't need a hint since it only fills one param though |
04:10 | <Justin Ridgewell> | Hopefully. |
04:22 | <pokute> | ({}).hasOwnProperty('foo') looks like someone typoed until the preceding :> is noticed: noPrototypeObject :> ({}).hasOwnProperty('foo') . Though it needs some inside-real-code visibility testing. |
04:25 | <pokute> | And realistic use cases too. While pipelines can be used in myriad of situations, I doubt this-call or bind-this will be used as variedly. We also need to dismiss code that's deliberately obfuscated in a way that people don't write such code. |
04:33 | <Justin Ridgewell> | I don't understand the example. |
04:34 | <Justin Ridgewell> | Did you mean noPrototypeObject :> ({}.hasOwnProperty)('foo') |
04:34 | <Justin Ridgewell> | (I for one really dislike the complexity that the non-identifier form of RHS introduces) |
04:36 | <pokute> | Did you mean |
04:54 | <rbuckton> | I can't say I'm too keen on an "elixir-style except pipe to the this binding" pipeline. It's much harder to reason over. |
04:56 | <rbuckton> | Looking at those two examples, I have no idea what's going on. |
04:56 | <rbuckton> | the
That way you only need the |
05:02 | <rkirsling> | that is pretty neat, actually |
05:03 | <rkirsling> | feels very well-integrated |
05:21 | <Justin Ridgewell> | That's part of why I dislike the non-identifier form. |
05:21 | <Justin Ridgewell> | But I' not convinced the this-arg is necessary. |
05:22 | <Justin Ridgewell> | Eg,
|
05:22 | <Justin Ridgewell> | Wouldn't require a syntax change |
05:56 | <rbuckton> | While I previously suggested `uncurryThis` for jschoi's function helpers proposal, it's downside is that it has to create a new function object (just like bind or PFA), where `f(this: x)` would just be a Call |
05:57 | <jschoi> | See also: https://github.com/js-choi/proposal-function-un-this |
05:57 | <jschoi> | (I would find only having a this-uncurrying function to be quite clunky, and I would like a special call syntax, whether it’s bind-this, call-this, or whatever. .call is very, very common and deserves to be optimized better than having to define an uncurried function every time…) |
05:58 | <rbuckton> | I think that's just the `uncurryThis` I mentioned above but with a different name |
05:58 | <jschoi> | Yeah. I split it into a separate proposal after the function-helpers omnibus proposal’s rejection. |
06:00 | <rbuckton> | IIRC, the argument was that "curry" was too overloaded with FP, but I think that's actually a positive rather than a negative since "to curry" in FP or lambda calculus has a very well defined meaning. |
06:01 | <jschoi> | https://github.com/js-choi/proposal-function-un-this/issues/1 |
06:02 | <jschoi> | Several people do seem to like “demethodize”. |
06:02 | <rbuckton> | ugh, thats a mouthful |
06:02 | <jschoi> | So is uncurryThis, heh. But yeah… |
06:02 | <jschoi> | …bikeshedding. |
06:03 | <jschoi> | I still like your (Did you ever mention why you think |
06:04 | <rbuckton> | Haskell Curry would be sad if we called it "demethodize" /s |
06:06 | <rbuckton> | That's funny, because I suggested it because of its similarity with TypeScript's function definition's parameter syntax. |
06:07 | <rbuckton> | I think f(arg0: x) would be great, but we already have f({ arg0: x }) . |
06:07 | <jschoi> |
Yeah, heh. I am referring specifically to bakkot’s most recent comment in the delegates room. |
06:07 | <rbuckton> | I would prefer real named parameters, honestly, because they work better with PFA than object binding patterns. |
06:10 | <Justin Ridgewell> | Options bags are nice, but the object overhead in hot functions. |
06:11 | <Justin Ridgewell> | It's a little similar to the destructure overhead of returning multiple values. |
06:11 | <rbuckton> | I keep hoping engines will optimize those away. I'm not sure if any do yet. |
06:12 | <Justin Ridgewell> | I don't think they'll ever |
06:13 | <Justin Ridgewell> | I really want register based mutli-return. |
06:13 | <Justin Ridgewell> | Something akin to Go |
06:13 | <rbuckton> | I want ref parameters and ref declarations, especially now that we have private fields. |
06:15 | <rbuckton> |
|
06:15 | <rbuckton> |
|
06:17 | <rbuckton> | It plays into the struct proposal somewhat as well. |
06:17 | <rbuckton> | https://github.com/rbuckton/proposal-refs |
06:18 | <Justin Ridgewell> | Ok, I'd take that, too. |
06:23 | <rbuckton> | I've been waiting to propose it when there are more motivating use cases. Other than the capabilities the feature itself unlocks, it is also valuable for decorators (to deal with circular references), and possibly for shared structs (i.e. Atomics.compareExchange(ref this.#x, 0, 1) ). But neither of those proposals are Stage 3 yet, and I have enough on my plate for the moment. |
10:31 | <rbuckton> | Between `f(this: x)` and `f(this x)`, the colon-suffix is necessary to avoid ambiguity with call: ```js f(this: (x)) f(this (x)) // Aready valid JS ``` It might be necessary for `ref`-expressions as well since they can be followed by parens (but not `ref` declarations): ```js f(ref x) // ok f(ref (x)) // ambiguous ``` Which could require `ref` to also use a `:` suffix for args, or a different token: ```js f(ref x) f(ref (x)) // ambiguous with call f(& x) f(& (x)) // ok, unambiguous f(&ref x) f(&ref (x)) // ok, unambiguous f(ref: x) f(ref: (x)) // ok, unambiguous const y = ref x const y = ref (x) // ambiguous with call const y = & x; const y = & (x)) const y = &ref x const y = &ref (x) const y = ref: x // meh const y = ref: (x) // meh ``` I'm not a fan of `ref:` in other expressions, so I might have to go with either a token like `&` or introducing a prefixed keyword syntax to allow us to introduce new keywords that shouldn't be treated as an identifier: ``` &keyword // &ref, &this %keyword ^keyword *keyword f(&this x) f(&ref x) &match (x) {} //no need for NLT ``` |
10:32 | <rbuckton> | (element for Android doesn't seem to like formatting code) |
19:32 | <pokute> | From what I've read here and in public github issue threads, it seems like the dataflow meeting didn't find any issues for pipeline operator itself. It seems like all the other suggested dataflow proposals would work very fine with the currently suggested hack pipelines. I'm glad! |
19:48 | <jschoi> | There are two representatives who have mild concerns about Hack pipes and expressed them at this week’s meetings, but not enough to block. |
19:48 | <jschoi> | (This is assuming that a bind-this/call-this/something-like-them operator also will advance; otherwise a third representative would switch their support to blocking.) |
19:48 | <jschoi> | One of the two representatives concerned about Hack pipes has written an essay (https://hackmd.io/yDDJCsS-Sv2AJwo8arAn3w?view) that we discussed a bit during a Thursday overflow meeting, and the other is planning to write her own article about them later. But neither representative plans to block Hack pipes, as far as I know. |
19:49 | <jschoi> | The other proposals (except for Function.pipe) are more controversial, such as bikeshedding bind-this vs. call-this and, even more controversially, Extensions and PFA syntax. |
19:49 | <jschoi> | So, yeah, basically yes: what you said. |
19:52 | <pokute> | Isn't this conflicting with, what seems to be my impression, issues raised on F# pipelines and PFA being considered separate proposals, with them having to go through the committee through their own merits too? |
19:53 | <pokute> | It seems that the issue was with many use cases of F# needing PFA, while now pipelines seem to require other proposals. |
19:55 | <jschoi> | I’m not sure what you mean; my apologies. F# pipes and PFA syntax are indeed separate proposals. But Hack pipes don’t require any other proposal, although they somewhat overlap with several proposals. F# pipes were considered but rejected for advancement several years ago, and PFA syntax was considered and rejected several months ago. But we can try to present either of them again in the future, if/when Hack pipes advance further first. And in the meantime I also plan to present Function.pipe, which are basically lightweight F# pipes. |
19:58 | <jschoi> | …Unless you’re responding to that essay I linked above from Hax? |
20:03 | <pokute> | On one hand, an issue raised for F# was: we must consider F# pipelines as a singular proposal, since PFA is a separate proposal. The F# and PFA proposals should stand on it's own merits since the other proposal might not advance. Now it seems like the success of hack pipelines proposal is linked to another proposal (bind-this/call-this/alternative). This was troublesome as both F# pipelines and PFA could be separated into separate proposals and have a reasonable use-case as such. Thus the combo of both, which had more power together, was usually not considered. I remember this being apparent in https://gist.github.com/tabatkins/1261b108b9e6cdab5ad5df4b8021bcb5 for example, (it seems I raised the concern on other gist). |
20:04 | <pokute> | Thus the weird situation where a combination of two proposals was not considered as a pro, but also the lack of combination of two proposals now being considered a con. |
20:06 | <jschoi> | Yes, we talked about the philosophy of considering each proposal on its own merits versus holistically considering all proposals. |
20:06 | <jschoi> | It’s a tension that I explicitly asked the Committee about. |
20:06 | <TabAtkins> | The problem pfa + f# pipes was that *if* you were judging them with the supposition that they'd both land, and one didn't, you'd be in a bad spot. And it wasn't clear both would land. |
20:07 | <jschoi> | Yes, for better or for worse, PFA syntax has always been very controversial and remains at high risk of never being accepted by the Committee. |
20:07 | <TabAtkins> | That doesn't imply that all proposals must be judged purely on their individual merits, it was a specific thing |
20:09 | <TabAtkins> | Aka, "don't worry, we'll have pfa to solve that" was a specific rejoinder to some usability complaints about f# pipes, and that was problem |
20:13 | <jschoi> | I think Jordan (ljharb) might have espoused the philosophy that all proposals should be judged primarily on their own merits. But Jordan would also agree, I know, that cross-cutting concerns between proposals should also always be considered. That’s why some representatives asked for this holistic analysis of a bunch of proposals. But, like Tab says, the big thing for each proposal is judging whether the proposal brings enough benefit…even if another proposal doesn’t also advance (especially if the other proposal is at high risk of never advancing). |
20:15 | <pokute> | Aka, "don't worry, we'll have pfa to solve that" was a specific rejoinder to some usability complaints about f# pipes, and that was problem |
20:17 | <jschoi> | If F# pipes and PFA syntax must go together that much, then coupling them into one proposal would be fine from my perspective. But the problem is that even PFA syntax alone has been controversial. Coupling F# pipes to PFA syntax means that F# pipes would never be able to advance unless PFA syntax ever garnered more support. |
20:17 | <ljharb> | imo if a proposal doesn't stand on its own merits, it must not advance - it should be combined with another one. |
20:17 | <ljharb> | the only gray area is if it stands on its own merits AND overlaps with another one that stands on its own merits, how OK is that |
20:20 | <pokute> | The latest PFA version funCall~(?, 1) , IIRC, was blocked, in part, due to lack of good use-cases, not by syntax. Merging it with F# would provide ample use cases. |
20:24 | <pokute> | Of course, that would mean two competing pipeline proposals at the same time, which has it's own problems. |
20:58 | <pokute> | Reading this all did make me a bit more concerned again. I believe that solutions to some of these issues do not belong into pipeline operator's scope. IMO Pipeline's scope is to not close the door to the solutions to issues outside it's immediate implementation. A statement of "We have addressed the raised issues A,B,C adjacent to pipeline operator and have discovered multiple different possible solutions to each one that are not blocked by the pipeline operator itself." should be sufficient. The risk with shouldering the solutions to those issues themselves is bloating the proposal and thus having it stuck. The proposal after all, is pipeline operator, not dataflow solution omnibus. :-) A bit more faith should be put on follow-up proposals. But maybe this has already been recognized and I'm just shouting at the choir. |
21:03 | <pokute> | And I do acknowledge that the dataflow discussion was specifically brought up due to concerns in TC39. |
21:16 | <pokute> | It is a delicate balance ... having the dataflow discussion within the context of pipeline operator proposal has it's benefits and it's detriments. A Benefit is that the discussion can go forward with pipeline operator as a priority. Detriments are that any problems with dataflow also become pipeline operator issues by association. /me delicately raises the possibility of a separate task force / working group for dataflow. |