That reminds me that I wanted to do a thorough search for proposals to add an operator for function composition -- those seem to be much harder to find than I thought ;-)
Yes, I think this would be useful -- but probably not only for Collection...
I've got an operator defined for this in my personal projects, along with an optional-propagating variant. They're very handy, but can be easy to overuse.
Reasons for this being in the standard library include:
A standard name for generally useful functionality.
Compile-time resolution to a plain function call. (@inlinable may handle this alreadyâŠ)
Reasons not to:
Many possible variants, some likely controversial: (how does one indent lists properly on Discourse?)
Input-returning, for functions with side-effects or dealing with reference-types (EG: view setup).
Taking a function with an inout parameter, returning the mutated copy of the input having called the function (EG: one liners for âgive me this value but having changed a propertyâ).
Mutating the input then returning the input, for symmetry with the reference-type/side-effect variant (proponents of ++ might like this one).
Optional-propagating versions of all variants.
No best spelling - the discussion will be entirely bikeshedding.
I'm all in favor of adding this, as an operator, as I think it helps a lot with readability in many cases, and think borrowing F#'s pipe forward |> is a good candidate for a spelling.
I am surprised that the only thread bringing that up has almost no activity. I miss this feature, too. Of course, one can easily write |>, but where to put it? Boilerplate it into every project? Make an extra framework just for that and boilerplate an otherwise useless import everywhere? The option that I went with was putting it into a framework that provides a lot of compositional functionality, but most of the time I end up using only |>. This should really be in the standard library.
This would be great if we were to add first-class language support for reactive streams (which we should consider doing - many languages have added it to their standard libraries already, such as Java).
If apply is implemented in Swift like it is in Kotlin it would be great if the closure drops the need for $0 since its implied that self would be returned. $0 in this closure would I guess be inout. Otherwise, you can ignore this.
This proposal seems closer to Kotlin's let function. where it takes the transform function and returns the result of that. In this case, the syntax of closures as is would suffice.
reference: https://kotlinlang.org/docs/reference/scope-functions.html#let
I agree with this in general, but in this case it being a function is key to its usefulness, since you canât put a function on the right-hand side of a result, and canât put a method on every type.
|> is also a fairly familiar concept from the command line (albeit with an extra character to avoid confusion with other meanings of |.
I think |> would be a great addition to the Swift standard library: it's a fairly established operator for its purpose, doesn't need compiler magic (you can't write an extension that works on every type), and its very presence in the standard library would probably encourage usage of operators in general, which is actually a strength of Swift.
Is the disambiguation really necessary? Iâm not particularly opposed to |>, but off the top my head it doesnât seem likely that someone would confuse âfunction applicationâ with âbitwise orâ.
Also, is this strictly for function application, or can we overload it to give us common mechanism for passing a T? to a f(_: T) -> U and getting back a U? (Iâm pretty sure thereâs a word for this, I just canât remember what it is)?
With compiler support we could make this available on all types. Implementing it as something that basically is a nameless method avoids conflicts with regular methods:
let includedProductIdentifiers = puzzleLibrary.volumes
.compactMap { volume in volume.productIdentifier }
.(Set.init)
or:
let includedProductIdentifiers = puzzleLibrary.volumes
.compactMap { volume in volume.productIdentifier }
.{ Set($0) }
It's nicely consistent to be able to continue chaining without requiring an operator for the last step. An operator might be more useful in different use cases though.
Is the disambiguation really necessary? Iâm not particularly opposed to |> , but off the top my head it doesnât seem likely that someone would confuse âfunction applicationâ with âbitwise orâ.
I did write an or operator in the past to glue together functions of type (X) -> Bool. If X happens to be itself Bool, there will be some confusion. To clarify, I do not advocate putting an or operator for boolean functions into the standard library, but I guess I am not the only one occasionally using such constructs as syntactic sugar in filter/allSatisfy/... .
I think this idea of "inline method definition" is worth exploring, yes, in order to check if it fits well with the rest of Swift syntax and constructs, and yet allows the flexibility needed by the wildest developers.
For me the main advantage of .{ ... } over |> is the built-in support for optional chaining.
I also foresee people focus a lot on the parenthesis in .(Set.init). Those are not regular parenthesis, and be ready to think hard about their exact role in the grammar.