Great! Looking forward to easier debug representation!
However, it think it would be a mistake to merge it as is - hopefully this is the first of many standard library macros - and it would be great to have a comprehensive plan for generalizing this and expanding the generated code for other things than debug description.
I’m thinking ofc of Rusts #[derive(Debug, Clone, PartialEq)]
macro system.
I see an opportunity here for a similar system - with the key difference that Swift already implicitly has Rusts #[derive(Clone, Copy)]
and that Swifts spelling for #[derive(PartialEq, Eq, Hash)]
is simply : Equatable, Hashable {}
and another important distinction is that Swift can declare the conformance to those protocols not only on the scope declaring the type, but also on an extension…
Since November last year I have been learning Rust, and now I mostly code Rust, after having coded Swift for soon 10 years. The Rust #[derive()]
system is great, and I think Swift would benefit from something similar - at least the part of an grammar for declaring a list of many macros to attach to a type.
Third party developers can also declare their own macros for conformance to their traits, which go into the same derive
trait (Swift: protocol) list - Rust does not discriminate standard library traits. E.g. the de facto industry standard crate (Swift: SPM target) serde has Serialize
(very similar to the automagical Encodable
in Swift) and Deserialize
(Swift: Decodable
), and they too can be included in the derive list, next to Rust standard library Debug
, like so:
#[derive(Debug, Serialize, Deserialize)]
.
I think it would be great the spelling would be:
#[attach(DebugDescription, Foo, Bar)]
struct Organization {}
Where attach
is a lets-defer-bikeshedding-of-keyword-tmp-keyword.
Personally I think it would be great if Equatable and Hashable would be forced go into thar list, because the magic that Swift has today which autosynthesises ==
and hash func really ought to “treated” as a macro generating code. Same thing for Codable… Codable is even more magical and strange, since eg the autosyntesised does not generate the enum CodingKeys
type, but creating such an enum is the way to rename keys. It is weird, and too much opaque magic IMO. I would love for Swift 7.0 to deprecate all the autosynthesized code, replaced by macros - so that we can expand the macro and see the generated code!! (Which is great as teaching and documentation!) - no magic! And then in Swift 8.0 we can remove that magic. Potentially we would keep the possibility of using those macros on extension
scopes, like we can today with extension Foo: Equatable {}
.
(but perhaps upgraded?! Because today doing extension: Foo: Codable {}
in a different module than the one declaring Foo
does not work, maybe with a macro Codable such restriction could be lifted?)
WDYT?