[Discussion] Inclusion of CasePaths into the language

How would those handlers be stored?

It's down to implementation really:

class Dispatcher<Event> {
    private var eventHandlers: [(Event) -> Void]

    func dispatch(event: Event) {
        for handler in self.eventHandlers {
            handler(event)
        }
    }
    func addHandler<Payload>(
        `for` matcher: CasePath<Event, Payload>,
        handler: (Payload) -> Void
    ) {
        let eventHandler = { (event: Event) in
            if let payload = event[casePath: matcher] {
                handler(payload)
            }
        }
        self.eventHandlers.append(eventHandler)
    }
}
1 Like

I don't think anyone is proposing a separate concept. Keeping things in the key path hierarchy is exactly what we'd want to do. Something like this could be a first step:

class CasePath<Root, Value>: KeyPath<Root, Value?>

For case paths and key paths to compose, we would also need writable, optional-chained paths, and then the hierarchy changes a bit:

class WritableOptionalPath<Root, Value>: KeyPath<Root, Value?>
class CasePath<Root, Value>: WritableOptionalPath<Root, Value>

There's also reference-writable paths to consider. And we have ideas there, too, but I'd rather not waste a ton of time on fleshing out the design before we have an engineer that has expressed interest in working on the project.

8 Likes

Yes, I am. CasePaths significantly reduces amount of boilerplate. And it would be great if CasePaths could interact with key-paths.

2 Likes

I definitely like casepaths although I agree that subscripts are not yet capable of supporting them (excpect if they give casepath subscript special treatment at compiler level).

While weā€˜re at it, Iā€˜d love to have

swich foo
{
case .bar(inout bar):
ā€¦
}

And (offtopic)

for inout foo in foos {ā€¦}

The difference is that CasePaths only handle one kind of case matching, although it is the most important one in that other kinds of case mostly have alternatives today:

// could be { $0 as? Subclass }
addHandler(for: case as? Subclass) { ... }

// could put the _ in the handler block instead
addHandler(for: case let .baz(a, _ c)) { a, c in ... }

// could be (for: { $0 as? Subclass}) { _ in ... }
addHandler(for: case is Subclass) { ... }

// hmm?
addHandler(for: case .foo(let count), .baz(_, _, let count)) { count in ... }
addHandler(for: case .foo(let count) where count > 3) { count in ... }

// Consistency bonus:
struct EnumLikeStuct: Equatable {
    private let value: String

    static let foo = EnumLikeStruct(value: "foo")
}

Dispatcher<EnumLikeStruct>.addHandler(for: case .foo) { ... }

If we were to add generalized destructuring case matching, which I saw suggested recently but canā€™t find right now, it would naturally also extend to captured cases:

addHandler(for: case (x, y) <- .destructuringMatch) { ... }

Just to add a big +. I would CasePaths to be an official part of the Swift language.

4 Likes

I would also like to express my support in favour of the inclusion of CasePaths into the language.

2 Likes

Here comes another enthusiastic +1.

2 Likes

+1 from me!

2 Likes

An exuberant +1 here too. (As another anecdote, I was at a virtual meetup this morning, and a few of us were lamenting that case paths have not already become part of the language. :smile: It was enough to cause me to write an unnecessary post this morning because my topic searching skills are relatively weak. :laughing: )

3 Likes

+1. I'd love to see case paths in the language.

3 Likes

+1 It's definitely great idea!

1 Like

+1 here also!

2 Likes

Maybe it's time to start a proper pitch/proposal?

2 Likes

I think there's plenty of appetite for the feature but nobody in the community outside of Apple seems to have both the appetite and the skill to provide an implementation (e.g.: here).

Another way this could get off the ground is for Apple to want it, but it seems they don't think it's a priority despite there being plenty of motivation, especially for SwiftUI.

I think case paths are amazing and it'd be great to have them built-in. I'd like to echo what others already said that it doesn't sound probable that Apple will implement something they don't immediately need though.

4 Likes

Massive +1 from me, too

For anyone interested, thereā€™s an active effort on Appleā€™s part on this. And AFAIK @stephencelis and @mbrandonw are writing up a pitch to put forward.

https://github.com/apple/swift/pull/58940

25 Likes

Further progress on this front with an initial pitch accompanying the implementation:

2 Likes