[swift-evolution] [Pitch] KeyPath based map, flatMap, filter
Elviro Rocca
retired.hunter.djura at gmail.com
Mon Jul 17 02:16:40 CDT 2017
Subscripts in Swift in fact have always looked to me like a way to make objects "callable", where you use brackets instead of parentheses: the difference of course is the fact that, when used point-free, the object will be considered an instance and not a function.
In this sense we could theoretically make a KeyPath callable by adding subscripts; consider the following code:
extension KeyPath {
subscript (get root: Root) -> Value {
return root[keyPath: self]
}
}
struct Person {
var firstName: String
var lastName: String
}
let x = Person.init(firstName: "Foo", lastName: "Bar")
let foo = (\Person.firstName)[get: x] /// "Foo"
This is valid Swift code (Swift 4.0 snapshot 2017-07-13). In theory a possible evolution of this could be referencing the subscript function in a point-free way like we can already do with regular functions:
let callable1 = (\Person.firstName)[get:] /// this won't compile
For the setter part, because the other half of a KeyPath is essentially a function of type (Value, inout Root) -> (), we could theoretically considering this kind of subscript function:
extension KeyPath {
subscript (set value: Value, on root: inout Root) -> () { /// this won't compile
root[keyPath: self] = value
return ()
}
}
let callable2 = (\Person.firstName)[set:,on:] /// this won't compile
But we cannot write subscripts with inout parameters. I actually find the subscript path a very interesting one to consider, but there's still a lot of machinery that's missing.
I would prefer two standardized prefix operators - for extracting the "(Root) -> Value" and the "(Value,inout Root) -> ()" parts of a KeyPath - to be added to the standard library. This is exactly the case where custom operators make sense: repeated operations that should be expressed with minimum code noise.
Elviro
> Il giorno 16 lug 2017, alle ore 18:34, Benjamin Herzog via swift-evolution <swift-evolution at swift.org> ha scritto:
>
> If it would be possible to make objects callable, wouldn't that also go
> in the same direction as subscripts currently? One could also implement
> it with the syntax for callable functions (in this case anonymous -
> without a name). Instead of this:
>
> subscript(index: Int) -> T
>
> we could also write
>
> func (_ index: Int) -> T
>
> On the call side it would change from this:
>
> list[3] to list(3)
>
> I know that it's not necessary and not even better readable, but it goes
> in the same direction in my opinion and is worth considering. What do
> you think?
>
> ______________________
>
> Benjamin Herzog
>
> On Wed, Jul 12, 2017, at 10:21 PM, Dave Abrahams via swift-evolution
> wrote:
>>
>> on Tue Jul 11 2017, Robert Bennett <rltbennett-AT-icloud.com> wrote:
>>
>>> Just realized that even inout functions don’t let you do
>>> member(object) = value.
>>
>> The other difference is that an inout function can't be used to get a
>> member from an immutable value, whereas a keypath/subscript/property
>> access can.
>>
>>
>> --
>> -Dave
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
More information about the swift-evolution
mailing list