Swift 5.8, Parsing, and You #290
Replies: 8 comments 20 replies
-
As always, great details and great examples to understand the changes.🎉 |
Beta Was this translation helpful? Give feedback.
-
Excited for the performance improvements and the |
Beta Was this translation helpful? Give feedback.
-
One of the projects I work on which uses swift-parsing has absolutely no issues with the change. Another project has a problem though. Please note, I've trimmed down this example/am using different type names, but the shape of everything is the same as in the real app! Given an input that contains either a double/floating-point number, or an empty string, e.g. enum ValueOrEmpty {
case value(Double)
case empty
static func parser() -> some Parser<Substring, Self> {
OneOf {
Double.parser().map(Self.value)
"".map { .empty }
}
} I get an error on the
I've tried changing the |
Beta Was this translation helpful? Give feedback.
-
Thank you for this write-up, I'll check these changes out and migrate as soon as possible. 👍 But this thread is kind of hidden and given that many people will upgrade to Xcode 14.3 very soon (we're in RC 2 already), I think this needs to be highlighted front and center. I personally think it would be great if there was a
|
Beta Was this translation helpful? Give feedback.
-
I did find an issues, but I think it is a swift bug. enum A {
private static let caseA1: some Parser<Substring, String> = Parse {
""
}.map{ return "A1"}
private static let caseA2: some Parser<Substring, String> = Parse {
""
}.map{ return "A2" }
struct ParserMe: Parser {
var body: some Parser<Substring, (String,String)> {
A.caseA1
A.caseA2
}
}
} |
Beta Was this translation helpful? Give feedback.
-
As an update to those watching, we've released: |
Beta Was this translation helpful? Give feedback.
-
Thanks for the excellent write up for working with v0.12. Made my update to https://github.com/bradhowes/swift-math-parser fairly straightforward. |
Beta Was this translation helpful? Give feedback.
-
I don't want to be annoying but since I didn't get any feedback in the dedicated discussion pointfreeco/swift-url-routing#79 I am asking here again: |
Beta Was this translation helpful? Give feedback.
-
Hey Parsing users!
Today we opened a pull request with some pretty big breaking changes in order to support Swift 5.8, which is bundled in Xcode 14.3, which just had a release candidate earlier this week. This discussion will cover what's changing, why, how to upgrade, and hopefully serve as a place to gather feedback before we merge the changes and cut a release.
Updated builders
The biggest (and breaking-est) change is a complete rewrite and overhaul of Parsing's result builders.
Parser builders were first introduced a little over a year ago, and remain a pretty advanced demonstration of Swift result builders. Parsing’s parsers are very flexible and generic (they can parse any input type into any output type), but we still wanted them to be as approachable and easy to use as possible, so we designed the builders with a number of overloads to help Swift infer if a parser was a substring or UTF-8 parser (two of the most common parsers that folks reach for when using the library). Unfortunately, these overloads accidentally exploited a type-checking flaw in Swift’s original result builders implementation, which is patched in 5.8.
So the bad news is these changes break existing result builders, including those defined in this library, and we don’t think it’s possible to provide a source-compatible upgrade process. The good news is we were able to rewrite Parsing’s builders to work with the new implementation, and these builders should be much more performant.
What do these changes look like in the library?
First, both
ParserBuilder
andOneOfBuilder
have been updated to be generic:ParserBuilder
is nowParserBuilder<Input>
OneOfBuilder
is nowOneOfBuilder<Input, Output>
These types are mostly hidden from the end user, but if you have implemented your own parsers that employ parser builders, you will need to update the
@ParserBuilder
annotation to be generic over its input:Second, to support these new generic builders, many parser conformances in the library have been updated with explicit
Input
generics so that the underlying builders can know what kind of input they are working with. For instance, theParse
parser is now explicitly generic over its input:This is because the underlying builder must know what
Input
is before it is evaluated:Had we relied on
Parsers.Input
instead, we end up with a bit of a chicken-egg problem:Where the result of
Parsers
depends on type-checking the builder, but type-checking the builder depends on knowing whatParsers.Input
is. This kind of bidirectional type-checking is prohibited in builders.While it is uncommon to specify the generics of a parser when working with the library, in the case that a user does, they may need to update these generic lists accordingly.
Likewise it is relatively uncommon to implement custom parser builders outside the library, but if you do, be sure to introduce a dedicated generic for the builder's
Input
, as relying on the associated type of the result is not allowed.Updated ways of entering builder syntax
Due to these changes, many top-level invocations of
Parse
andOneOf
may stop working:There are several ways to fix this.
The simplest is to use the new
input
parameter ofParse
andOneOf
:You can also specify the input and output explicitly with opaque result types:
Or you can take advantage of a brand new feature of the release, which allows you to define parsers similar to how you define SwiftUI views:
Once these top-level changes are made, our hope is that most existing parsers will continue to build.
We want your feedback
If you use Parsing in a project, please take the PR’s branch for a spin and let us know what you think, and let us know if you encounter any issues migrating.
Special thanks to @JaapWijnen for communicating with the Swift team about the impact of their result builder changes on Parsing, and for experimenting with the generic builders that ended up in this release.
Beta Was this translation helpful? Give feedback.
All reactions