I don't think the struct functionality makes much sense. There are two ways you
can use the struct<...> construct:
So does `enum<>` makes not much sense, I guess? I can’t think of any use-case
were `enum<>` could do something what `struct<>` can’t.
1. struct<SomeConcreteStruct, Protocol1, Protocol2>. In this case the
struct<...> representation is unnecessary; the protocols that are available to
the user are known at compile-time, and structs can't have subtypes that
conform to additional protocols like classes can. There is an example marked
"func boo(value: struct<SomeStruct>) /* equivalent to */ func boo(value:
SomeStruct)"; my question is why having more than two ways to express the same
idea makes the language better, easier to use, etc.
Was this clarified somewhere, I mean that value types won’t have subtypes ever?
This would be nice to know.
We already can write the same (ugly) scenario with protocols:
protocol A {}
extension A {
func foo() {
print("foooo")
}
}
// this is the refined design that we all use
func boo(value: A) {
value.foo()
}
// this might be the original design
func zoo(value: protocol<A>) {
boo(value)
}
struct B: A {}
let value = B()
zoo(value)
boo(value)
The main idea behind `struct<>` etc. is not to make the language complicated,
but to add symmetry to the type system, which should already have been there
from the beginning. Compared to the little example I just wrote, we all already
use the refined format of the (not present) base `struct<>`.
So if value types might have subtypes one day, this wouldn’t be hard to upgrade
I suppose. Anyways I’ll move that part of the proposal to the future direction.
2. struct<T, Protocol1, Protocol2>. In this case struct<...> is being used as
an add-on to the generics system to denote a 'must be value type' constraint.
However, I think a 'T : class'-like 'struct' constraint makes more sense, both
because it fits better with the existing 'class' constraint and because it can
be used anywhere the generic system allows a type parameter to be constrained.
A generic 'struct' constraint would give the currently generics system as much
expressive power as struct<...>.
True, but I feel like there is a change incoming in that direction
([swift-evolution] Should we rename "class" when referring to protocol
conformance?) and I don’t think the core team will decide to introduce `T:
class`-like `struct` or `enum` constraint. :/
struct C<T: struct where T: SomeProtocol> {
var value: T?
func set(value: T) {
self.value = value
}
}
This would be nice to have. And yes this does look way better than:
struct C<struct<T, SomeProtocol>> {
[…]
}
But isn’t this again a refined usage of the base format (`struct<>` in this
case)!?
One other example that comes to mind, where I can’t really tell if this would
be possible to express with `struct<>`, can be defined outside of the generic
scope just like `class<SomeBaseClass, SomeProtocol>` or `all<SomeBaseClass,
SomeProtocol>`:
var structArray: [struct<Any, SomeProtocol>]
Would this work? This is an interesting case, where no values inside the struct
can be reference-types!
Overall, rather than having this be a separate feature I think it should be
developed as part of the "Generalized Existentials" feature that is already on
the roadmap for Swift 3. The cases where adding class<...>, struct<...>, etc
can improve expressive power are covered by allowing variables to take
existential types with constraints. The one big feature that Generalized
Existentials should absorb from this proposal is allowing the representation of
a concrete class type with protocol constraints (<MyClass, SomeProtocol,
AnotherProtocol>).
Is there any reading you can point me to, so I can include or quote it into the
proposal?
--
Adrian Zubarev
Sent with Airmail
Am 14. Mai 2016 bei 06:06:12, Austin Zheng ([email protected] ) schrieb:
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution