I'm enthusiastically in favor of this proposal. This would be a surprisingly radical change to the aesthetics of the language -- but I believe the change would be for the better.
Before Codable was a thing, I used to have a fun side project for Swift serialization. One of the file formats of that project was text-based, with a syntax inspired by Swift's literals and initializers -- think JSON but with Swift syntax and lightweight types. For that project, I decided to implement comma elision (exactly as proposed), and the result felt incredibly right.
Swift has thoroughly spoilt me with its semicolon elision -- I can't work in C++ anymore without constantly getting annoyed at the darned things. After a mere few hours of working in my toy language, I started feeling the exact same way about commas, and they've annoyed me ever since.
My toy language was strictly limited to data construction primitives, with no enums and no expression syntax, so no ambiguities could ever arise from omitting commas. This is not the case with Swift itself, but I'm satisfied with the solution given -- the parsing rules given are reasonably straightforward and they seem implementable by automated formatter tools.
If the proposal is accepted, the comma elision parsing rules will have some API naming consequences -- we should add labels to any parameters in the second and subsequent position that we expect will often begin with a dot. Luckily, I believe we already tend to do this.
On the other hand, it has to be pointed out that Array literals containing enum-like values (enums, OptionSets, etc.) will unfortunately often require commas even with this proposal.
I believe this is why the EDSL example used weird free-standing functions to specify table column types. Most Swift programmers would've used enums there, since that simplifies entry through code completion. Unfortunately, enums wouldn't work nearly as well:
let table = Table(
name: "Employees"
columns:
.guid("record_id", isPrimaryKey: true, nullable: false),
.guid("manager_id", isPrimaryKey: false, nullable: true),
.string("name", length: 1024, nullable: false),
.int64("employee_id", nullable: false),
.date("start_date", nullable: false)
)
Note how we're still required to add four (but not five!) commas. This is unfortunate, but it's not too difficult to work around, as long as we're designing the DSL from scratch:
let table = Table(
name: "Employees"
columns:
Column(.guid, "record_id", isPrimaryKey: true, nullable: false)
Column(.guid, "manager_id", isPrimaryKey: false, nullable: true)
Column(.string, "name", length: 1024, nullable: false)
Column(.int64, "employee_id", nullable: false)
Column(.date, "start_date", nullable: false)
)
Perhaps this would've made a more convincing example. I expect code completion would make this nearly as easy to enter as the enum variant above.
Unfortunately, we already have at least one DSL in widespread use that wasn't designed with comma elision in mind. SPM's Package.swift files tend to be full of arrays of enum cases, and the proposal has limited effect on these:
// Adapted from https://github.com/apple/swift-protobuf/blob/master/Package.swift
import PackageDescription
let package = Package(
name: "SwiftProtobuf"
products: [
.executable(name: "protoc-gen-swift", targets: ["protoc-gen-swift"]),
.library(name: "SwiftProtobuf", targets: ["SwiftProtobuf"]),
.library(name: "SwiftProtobufPluginLibrary", targets: ["SwiftProtobufPluginLibrary"]),
]
targets: [
.target(name: "SwiftProtobuf"),
.target(name: "SwiftProtobufPluginLibrary"
dependencies: ["SwiftProtobuf"]),
.target(name: "protoc-gen-swift"
dependencies: ["SwiftProtobufPluginLibrary", "SwiftProtobuf"]),
.target(name: "Conformance"
dependencies: ["SwiftProtobuf"]),
.testTarget(name: "SwiftProtobufTests"
dependencies: ["SwiftProtobuf"]),
.testTarget(name: "SwiftProtobufPluginLibraryTests"
dependencies: ["SwiftProtobufPluginLibrary"]),
]
swiftLanguageVersions: [.v3, .v4, .v4_2, .version("5")]
)
Is it time for another Package.swift redesign?
let package = Package(
name: "SwiftProtobuf"
products: [
Executable(name: "protoc-gen-swift", targets: ["protoc-gen-swift"])
Library(name: "SwiftProtobuf", targets: ["SwiftProtobuf"])
Library(name: "SwiftProtobufPluginLibrary", targets: ["SwiftProtobufPluginLibrary"])
]
targets: [
Target(name: "SwiftProtobuf")
Target(name: "SwiftProtobufPluginLibrary"
dependencies: ["SwiftProtobuf"])
Target(name: "protoc-gen-swift"
dependencies: ["SwiftProtobufPluginLibrary", "SwiftProtobuf"])
Target(name: "Conformance"
dependencies: ["SwiftProtobuf"])
TestTarget(name: "SwiftProtobufTests"
dependencies: ["SwiftProtobuf"])
TestTarget(name: "SwiftProtobufPluginLibraryTests"
dependencies: ["SwiftProtobufPluginLibrary"])
]
swiftLanguageVersions: [Version3, Version4, Version4_2, Version("5")]
)
Would code completion be smart enough to make this as easy to enter as the original enum-based variant above?