Closed sharplet closed 9 years ago
Early on I avoided overloading to provide both curried & uncurried functions since the result could be achieved by composition. Case in point, curry(flip(map)) { i in (i, key(i)) }
should work today, I think? (At some cost to elegance.)
Somewhat damningly, overloading flip
to curry
as well is overloading strictly on the return type, which can cause some frustrating ambiguities.
Ultimately, I need to decide to what extent Prelude wants to make up for Swift’s design flaws vs. providing simple, unambiguous tools that you can apply to work around them. Phrasing it like that, neither of those sound very good :sob:
As you note, I’ve already gone some distance towards the former with <|
and |>
; I would typically write:
func sortedBy<S: SequenceType, Key>(seq: S, key: S.Generator.Element -> Key) -> [S.Generator.Element] {
return lazy(seq)
|> (flip(map) <| { i in (i, key(i)) })
|> (flip(sorted) <| { a, b in a.1 < b.1 })
|> (flip(map) <| { i, _ in i })
}
(Again, at some cost to elegance!)
I’m torn. I’d be very curious to know what consumers of the API think. Should Prelude 2.0 break backwards-compat to attempt to make functional Swift more elegant by e.g. currying by default?
My preference would be to leave flip alone, and put curry(flip(f))
(which did indeed work correctly @robrix, at least in all my limited testing over here and with your sorted |> map |> String.join
example in the README) into a separate function. I want to call it flurry
, because :sunglasses:
The other option would be a postfix operator (which it turns out has actually been tried before), and while this comes with all the overhead of operators, I still love it.
func sortedBy<S: SequenceType, Key>(seq: S, key: S.Generator.Element -> Key) -> [S.Generator.Element] {
return lazy(seq)
|> map~ { i in (i, key(i)) }
|> sorted~ { a, b in a.1 < b.1 }
|> map~ { i, _ in i }
}
Amusingly, I actually discovered this morning that I had written the operator version, but had just not committed or pushed it yet. I'll go throw that in a PR in case you want it.
Having given this more thought, I don’t think I want Prelude to offer a combined curry/flip operator. Prelude has not thus far been in the business of fixing Swift’s design decisions, and I think that’s a reasonable charter for it to continue with, at least for the present.
Sounds like a reasonable approach. Appreciate you taking the time to consider it! ✨
On Mon, 6 Apr 2015 at 23:16 Rob Rix notifications@github.com wrote:
Closed #38 https://github.com/robrix/Prelude/issues/38.
— Reply to this email directly or view it on GitHub https://github.com/robrix/Prelude/issues/38#event-274119802.
Take this (not so) hypothetical implementation of a Schwartzian transform that makes use of curried, flipped versions of some standard library functions:
Currently I need to hand-write those curried, flipped versions of
map
andsorted
.Given that Prelude already provides
|>
and<|
, making this kind of chaining possible—would it also sense to have a combined curry & flip function? Then this would be achievable using only Prelude, like so:I'm not sure if you'd really want to overload the existing
flip
function as implied here, but perhaps there's an alternative name?