00:00 | <Justin Ridgewell> |
I think I just refuted that. |
00:00 | <Justin Ridgewell> | It exactly overlaps with pipeline+uncurry |
00:00 | <TabAtkins> | No? You said call-this overlaps with uncurry. |
00:01 | <TabAtkins> | Right, because call-this and uncurry are the same thing in different syntaxes. |
00:03 | <Justin Ridgewell> | My goal here is to allow fluent APIs with acceptable synatx |
00:03 | TabAtkins | is heading home for the day, will have to continue later |
00:03 | <Justin Ridgewell> | I don't think pipeline and normal methods looks appealing |
00:03 | <Justin Ridgewell> | Pipeline as a chain of free functions is fine |
00:04 | <Justin Ridgewell> | But mixing in a chained method on an object in the pipe and it starts to have warts |
00:04 | <Justin Ridgewell> | Mixing methods and bind-ops works perfectly |
04:53 | <ljharb> | pipeline can’t handle call-this/uncurry without a special operator |
04:54 | <ljharb> | the operator could be call-this, or bind-this, or something else, but it can’t be done with pipeline alone |
04:55 | <ljharb> | i agree that bind-this is the one that fits into an OOP method chain without pipeline, which is useful. |
20:07 | <TabAtkins> | So the issue that's gonna continue to bite is that, from the feedback we've gotten, having bind-this able to do essentially the same thing as pipe is a Problem. It might turn out to be sufficiently okay to look past, but as it is this is the precise sort of overlap that has been called out as making committee members uncomfortable. |
20:10 | <TabAtkins> | And the arguments against "fluent API via bind-this" are precisely the same arguments against "fluent API via F# pipe", which is that it will encourage authors to write libraries intended specifically to be called this way, which means they're harder or awkward to call in the traditional way, and won't work with any other feature that expects functions, like something that takes callbacks - they'll have to be wrapped in an arrow func instead. (For example, it won't work with PFA, if you want the receiver to be the thing placehold'd.) |
20:11 | <TabAtkins> | Part of the reason we fought so hard for Hack pipes is precisely because it works reasonably well for all of these cases. Yes, it's not the local minimum for fluent APIs, but it's hovering just outside of it, and without the additional downsides that come from seeking that minimum. |
20:14 | <TabAtkins> | And I'll note that in the previous code sample, the pipe code was written badly. When done correctly, it's roughly identical to the bind-this code:
|
20:15 | <TabAtkins> | The only difference (an unavoidable one) is, as always, having to put the topic value in the arglist, rather than it being passed implicitly in some way. But that's it, vs the extra code and additional indentation that the previous code sample unnecessarily burdened it with. |
20:56 | <ljharb> | that pipe example is fine with me, to be sure. however, if
instead of, as with the bind-this proposal:
|
21:54 | <TabAtkins> | Yes, so you, of course, would not write a library with export function uniq() { return [...new Set(this)]; } , you'd write it as export function uniq(arr) {...} |
21:55 | <TabAtkins> | Rather than there now being three potential ways to write a function (as a method, as a this-using free fucntion, or as a this-less free function), we stick with the two that we currently have. |
22:08 | <TabAtkins> | But if you'd extracted uniq() from a class because of robustness, then yes, you'd write it in the first style with the call-this operator. |
22:09 | <TabAtkins> | The alternative is an uncurry operator that just produces a fresh function a la fn.call.bind(fn) |
22:09 | <TabAtkins> | Then it's just |> uniq(##) |
22:16 | <jschoi> | (I am neutral between a bind-this operator receiver |> #::fn() and a call-this operator receiver |> fn::(#) , but I would rather have either than a demethodize operator receiver |> (::fn)(#) .) |
22:39 | <ljharb> | Those three already exist |
22:40 | <TabAtkins> | You can't just say things like that when you mean "you can do these by calling Function methods" ^_^ |
23:37 | <Justin Ridgewell> |
|
23:40 | <Justin Ridgewell> | And the arguments against "fluent API via bind-this" are precisely the same arguments against "fluent API via F# pipe", which is that it will encourage authors to write libraries intended specifically to be called this way, which means they're harder or awkward to call in the traditional way, and won't work with any other feature that expects functions, like something that takes callbacks - they'll have to be wrapped in an arrow func instead. (For example, it won't work with PFA, if you want the receiver to be the thing placehold'd.) |
23:41 | <TabAtkins> | No, F#-style just requires your function to accept one of its arguments as a second, unary call. There's no fundamental difference between fn(a, b)(c) and c::fn(a, b) , they're both just accepting one of their arguments in a special way that's not part of the arglist. |
23:42 | <Justin Ridgewell> | There's a huge difference with creating a closure and passing arguments to a single function. |
23:43 | <TabAtkins> | function fn(a, b) { this=>{...}} can even have the exact same body as a this-using function. ^_^ |
23:44 | <TabAtkins> | There's not really? Like, sure, yeah, they're different, and there's internal stuff. But semantically they're the same. JS distinguishes them; Haskell doesn't; it's just a syntax choice. |
23:46 | <Justin Ridgewell> | We shot down F# because of the temporary closures it requires to do anything non-trivial. Even if the runtime output would be the same, I don't think it's fair to compare bind-op to F#. |
23:52 | <TabAtkins> | That was one of the reasons, yes. (Luckily one that excited the impls so we could lean hard on it.) It was definitely not the only. |
23:53 | <TabAtkins> | The ecosystem-forking effect (libraries being written explicitly for pipeline, authoring all their functions as unary-returning) was another reason; we did not want that to happen. And that precise argument applies equally to bind-this. |
23:57 | <jschoi> | For what it’s worth, a few months ago, I raised the ecosystem-forking concern regarding bind-this before in this channel, since it had already been raised in plenary by Waldemar Horwat against Hax’s extensions proposal. At the time I raised that concern about bind-this here, Jordan (and I think maybe even Tab?) said that the ecosystem-forking risks between bind-this and extensions were “different”, but I still can understand why it may be a concern. I wonder what Waldemar would think, being the one who had raised it for extensions. |
23:58 | <Justin Ridgewell> |
I don't agree with this. My understanding of the consensus was encouraging a fully functional, make closures-everywhere was a bad idea. Not that ecosystem fork is a huge issue, and certainly not enough that we'd block entirely. |