[swift-evolution] [Pitch] KeyPath based map, flatMap, filter

Benjamin Herzog mail at benchr.me
Sat Jul 22 12:29:46 CDT 2017

I also thought about adding a computed property or method to KeyPath to
get the callable behaviour, but it is really hard to distinguish between
the keypath and it's method, especially in the literal syntax. Adding a
separator like # would help but would bring the same new complexity like
a prefix operator. If we add something like this it should be there for
a broader use in my opinion.

After thinking a bit more about the topic I tend more to add callable
behaviour to instances via a keyword. Background is that I found
similarities to `init`.

`init` is a keyword in Swift which is called on the type name with given
parameters and always return `Self` (`init?` returns `Self?`). So I
think it would be consistent to add another keyword which enables the
same thing on an instance basis. Like `init` it could also be overloaded
and in this case even return different types.

My first proposal is `call` but this could be a bit too generic and
could also break existing code, so if you have better name suggestions
go ahead! :)

An example could look like this:

class ArrayWrapper<Element> {
    private var elements: [Element]
    // `init` as keyword is called on static level -> KeyPath(root: )
    init(elements: Element...) { self.elements = elements }
    // `call` as new keyword would make the object callable
    call(index: Int) -> Element { return self.elements[index] }

let a = ArrayWrapper(elements: 1, 2, 3)
a(index: 1) // a can now also act as a function 2

In this case, `a` could also be used as a normal function taking an
`Int` as parameter and returning an `Int` (because `Element` is replaced
by `Int`) after calling.

func someFunction(f: (Int) -> Int) -> Int {
	return f(1)
someFunction(f: a) // 2

In the same manner this could be implemented for KeyPath<Root, Value> to
act as (Root) -> Value. It could also act as a setter lens by having one
parameter declared as `inout`.

What do you think about this?

Benjamin Herzog

On Mon, Jul 17, 2017, at 02:03 PM, Tino Heth via swift-evolution wrote:
> I hope for Swift meta-programming features evolving alongside reflection
> (both topics imho still need a complete concept):
> How about
> collection.map(MyObject.myProperty.get)
> or, to avoid possible ambiguity, something like
> collection.map(.myProperty#get)
> ?
> _______________________________________________
> 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