[swift-evolution] [Pitch] Add the DefaultConstructible protocol to the standard library

Xiaodi Wu xiaodi.wu at gmail.com
Mon Dec 26 00:15:43 CST 2016


On Mon, Dec 26, 2016 at 1:10 AM, Daniel Leping <daniel at crossroadlabs.xyz>
wrote:

> I'm giving a wider range, which is about ANY factory pattern related
> stuff. Doesn't look to be narrow to me.
>

I thought factory methods were regarded as undesirable in Swift? One of the
stated reasons for failable initializers was: "Failable initializers
eliminate the most common reason for factory methods in Swift... Using the
failable initializer allows greater use of Swift’s uniform construction
syntax, which simplifies the language by eliminating the confusion and
duplication between initializers and factory methods." <
https://developer.apple.com/swift/blog/?id=17>


On Mon, 26 Dec 2016 at 11:38 Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
>> On Mon, Dec 26, 2016 at 12:58 AM, Daniel Leping <daniel at crossroadlabs.xyz
>> > wrote:
>>
>> Well, reflection is a huge performance drop. Protocol conformance is way
>> better.
>>
>>
>> I'm not sure how huge it would be in the grand scheme of things; in your
>> example, you are still evaluating a train of protocol conformances and
>> casting at runtime. Of course, compiler magic can be fast, but I still
>> don't see how this is a "very common use case" (as you write) that would
>> justify magic equivalent to that for Objective-C bridging, which is what
>> you're saying it should be. If `DefaultConstructible` is useful only when
>> it's magic and the specific use case is dependency injection/inversion of
>> control, then we're getting very specialized here.
>>
>>
>> On Mon, 26 Dec 2016 at 11:26 Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>
>> On Mon, Dec 26, 2016 at 12:50 AM, Daniel Leping <daniel at crossroadlabs.xyz
>> > wrote:
>>
>> I'm not arguing for implicit conformance in general, but I'm telling that
>> DefaultConstructable is the same basic level as AnyObject, which is
>> conformed implicitly.
>>
>> Shortly, I'm against implicit conformance in general. I'm positive with
>> "automatic compiler magic" conformance to DefaultConstructable for any
>> object having a default constructor as it really is a very basic stuff.
>> Otherwise you will have to add explicit conformance to it in almost every
>> class of yours (annoying).
>>
>>
>> Well, this sounds very different from Adam's proposal, where he proposes
>> semantic meaning for `init()` that, as he described, means that it cannot
>> apply to every type that implements `init()`. However, he also just said
>> that he thinks that all types with `init()` should conform, so I guess I'm
>> confused which way that is.
>>
>> At base, you want a way of knowing if a type has `init()`. That sounds
>> like reflection to me, not protocol conformance. For the record, I look
>> forward to the day when AnyObject magic is removed; I assume it is coming
>> eventually.
>>
>>
>> On Mon, 26 Dec 2016 at 11:14 Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>
>> On Mon, Dec 26, 2016 at 12:43 AM, Daniel Leping via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> Thank you, Adam!
>>
>>
>> Wait, are you arguing for implicit conformance or not?
>>
>> On Mon, 26 Dec 2016 at 11:12 Adam Nemecek via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> > Swift doesn't do implicit conformance.  It always has to be declared
>> explicitly.  I'm pretty sure Doug Gregor can explain why better than I
>> could.
>>
>>
>> I don't think Daniel was arguing for implicit conformance, he's saying
>> that if it makes sense for an object to have a default constructor, it
>> makes sense for it to conform to the protocol which I agree with 100%.
>>
>> On Sun, Dec 25, 2016 at 9:17 PM, Dave Abrahams via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>>
>>
>>
>> on Sun Dec 25 2016, Daniel Leping <swift-evolution at swift.org> wrote:
>>
>>
>>
>>
>>
>> > You are right, usually it's required to implement a protocol which is
>> not a
>>
>>
>> > good approach. The best is plain objects which can be used
>> independently of
>>
>>
>> > ORM if needed (as DTOs, i.e.).
>>
>>
>> >
>>
>>
>> > I was thinking of DefaultConstructable as a protocol automatically
>> applied
>>
>>
>> > to any class/struct having a default init, which is really logical for
>>
>>
>> > me.
>>
>>
>>
>>
>>
>> Swift doesn't do implicit conformance.  It always has to be declared
>>
>>
>> explicitly.  I'm pretty sure Doug Gregor can explain why better than I
>>
>>
>> could.
>>
>>
>>
>>
>>
>> > On Mon, 26 Dec 2016 at 9:41 Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>
>>
>> >
>>
>>
>> >> On Sun, Dec 25, 2016 at 10:50 PM, Daniel Leping
>>
>>
>> >> <daniel at crossroadlabs.xyz>
>>
>>
>> >> wrote:
>>
>>
>> >>
>>
>>
>> >> Ok, an example from ORM. You have an entity factory with a virtual
>> (read,
>>
>>
>> >> overloadable in the subclasses) method populating the properties.
>>
>>
>> >> DefaultConstructable is a great choice here. Otherwise you will have to
>>
>>
>> >> force the users of your ORM to implement a certain protocol, which you
>> most
>>
>>
>> >> probably would like to avoid.
>>
>>
>> >>
>>
>>
>> >>
>>
>>
>> >> Sorry--I'm not very familiar with using Swift for ORM purposes. Why do
>> you
>>
>>
>> >> want to avoid having your users conform to a certain protocol?
>> Wouldn't the
>>
>>
>> >> users of your ORM have to conform to `DefaultConstructible` then? I'm
>>
>>
>> >> looking at Swift ORMs, and all require users to conform to a protocol
>> or
>>
>>
>> >> inherit from a base class, typically named `Model` or similar. From a
>> quick
>>
>>
>> >> Google search:
>>
>>
>> >>
>>
>>
>> >> https://vapor.github.io/documentation/fluent/model.html
>>
>>
>> >> https://github.com/blitzagency/amigo-swift
>>
>>
>> >>
>>
>>
>> >>
>>
>>
>> >> In general I think the best showcase is generic factories.
>>
>>
>> >>
>>
>>
>> >> On Mon, 26 Dec 2016 at 9:02 Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>
>>
>> >>
>>
>>
>> >> On Sun, Dec 25, 2016 at 10:18 PM, Daniel Leping
>>
>>
>> >> <daniel at crossroadlabs.xyz>
>>
>>
>> >> wrote:
>>
>>
>> >>
>>
>>
>> >> Usually it's a generic function that needs to return a value from some
>>
>>
>> >> other function or a default value (zero) in a case of some conditions.
>>
>>
>> >> Optional value is an arguable solution in quite some scenarios. Afaik,
>>
>>
>> >> sometimes it can be used for optional resolution.
>>
>>
>> >>
>>
>>
>> >>
>>
>>
>> >> Right, I'd agree that Optional is the idiomatic way to do it. Afaict,
>>
>>
>> >> there's not much you can do with a default value that you couldn't with
>>
>>
>> >> nil, unless you have some guarantee as to _what_ that default is;
>> however,
>>
>>
>> >> I'd expect that in every case that you can rely on a guarantee about a
>>
>>
>> >> default value which would be more useful than nil, it's going to
>> require
>>
>>
>> >> more specific knowledge of your type than an all-encompassing
>>
>>
>> >> `DefaultConstructible` can provide.
>>
>>
>> >>
>>
>>
>> >> Also, generic factories. Widely used in ORM solutions.
>>
>>
>> >>
>>
>>
>> >>
>>
>>
>> >> Can you elaborate on this? Why is Optional not a solution here?
>>
>>
>> >>
>>
>>
>> >>
>>
>>
>> >> As mentioned above, algorythmical stuff that requires Zero.
>>
>>
>> >>
>>
>>
>> >>
>>
>>
>> >> I'm still not convinced there exist credible use cases that need to be
>>
>>
>> >> generic over both collections and floating point, for instance. In
>> fact, in
>>
>>
>> >> my experience, there are few math-heavy algorithms where one can ignore
>>
>>
>> >> even the distinction between integers and binary floating point. By the
>>
>>
>> >> time you get down to matrix math, you start to run into difficulties
>> that
>>
>>
>> >> require separate implementations for Float and Double.
>>
>>
>> >>
>>
>>
>> >> On Mon, 26 Dec 2016 at 8:38 Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>
>>
>> >>
>>
>>
>> >> Can you give some examples of what you used this approach to do?
>>
>>
>> >>
>>
>>
>> >>
>>
>>
>> >> On Sun, Dec 25, 2016 at 9:49 PM, Daniel Leping
>>
>>
>> >> <daniel at crossroadlabs.xyz>
>>
>>
>> >> wrote:
>>
>>
>> >>
>>
>>
>> >> +1 to this approach. I remember I had to create it on my own for my
>>
>>
>> >> projects. Would be nice to have it out of the box.
>>
>>
>> >>
>>
>>
>> >> On Mon, 26 Dec 2016 at 8:11 Adam Nemecek via swift-evolution <
>>
>>
>> >> swift-evolution at swift.org> wrote:
>>
>>
>> >>
>>
>>
>> >> > Yes, those particular types have initializers that take no arguments.
>>
>>
>> >> That does not address my question. You merely restated your initial
>>
>>
>> >> observation that many types in Swift have implemented `init()`.
>>
>>
>> >>
>>
>>
>> >> Right, it's an empirical argument.
>>
>>
>> >>
>>
>>
>> >> > I didn't think the value returned by `init()` was regarded as any
>> sort
>>
>>
>> >> of zero--or even any sort of "default." In fact, some types in
>> Foundation
>>
>>
>> >> have a static property called `default` distinct from `init()`.
>>
>>
>> >>
>>
>>
>> >> Let's not talk about those then. This would not apply to every single
>> type
>>
>>
>> >> in existence, as I've stated previously.
>>
>>
>> >>
>>
>>
>> >> > It gives you something different every time. How can this be squared
>>
>>
>> >> with your stated motivation regarding concepts of zero and concepts of
>>
>>
>> >> equality?
>>
>>
>> >>
>>
>>
>> >> Due to the fact that it's a resource, not a value. As I've stated
>> above,
>>
>>
>> >> not all of this applies to types that are more resource-like.
>>
>>
>> >>
>>
>>
>> >> > Or, it's what you get because that's the most trivial possible
>> string.
>>
>>
>> >> Quite simply, I do not think the designer of most types that implement
>>
>>
>> >> `init()` have paused to wonder whether the value that you get is the
>>
>>
>> >> identity element associated with the most useful and prominent
>> operation
>>
>>
>> >> that can be performed on that type. I certainly never have.
>>
>>
>> >>
>>
>>
>> >> This is an appeal to tradition.
>>
>>
>> >>
>>
>>
>> >> > The statement I wrote was in JavaScript, so I'm not sure what you
>> mean
>>
>>
>> >> by returning an optional. `[].reduce((a, b) => a + b)` results in an
>>
>>
>> >> error in JavaScript. In Swift, such a function may also be implemented
>> with
>>
>>
>> >> a precondition that the array is not empty and would not return an
>> optional.
>>
>>
>> >>
>>
>>
>> >> I was talking about their analogous swift implementations.
>>
>>
>> >>
>>
>>
>> >> > Can you give an example of an algorithm dealing with tensors where
>> you
>>
>>
>> >> would use a `DefaultConstructible` generic over all types that have
>>
>>
>> >> `init()`, as opposed to working with the existing `Integer`,
>>
>>
>> >> `FloatingPoint`, and other numerical protocols?
>>
>>
>> >>
>>
>>
>> >> If it's implemented as either nested collections or numbers.
>>
>>
>> >>
>>
>>
>> >>
>>
>>
>> >>
>>
>>
>> >> On Sun, Dec 25, 2016 at 6:00 PM, Xiaodi Wu <xiaodi.wu at gmail.com>
>> wrote:
>>
>>
>> >>
>>
>>
>> >> On Sun, Dec 25, 2016 at 7:30 PM, Adam Nemecek <adamnemecek at gmail.com>
>>
>>
>> >> wrote:
>>
>>
>> >>
>>
>>
>> >> >  Is it well settled, either in Swift or in C++/Rust/etc., that the
>> value
>>
>>
>> >> returned by a default initializer/constructor is regarded as an
>> identity
>>
>>
>> >> element or zero?
>>
>>
>> >>
>>
>>
>> >> Int() == 0, String() == "" so to some extent by convention, a lot of
>> types
>>
>>
>> >> have a default value as is.
>>
>>
>> >>
>>
>>
>> >>
>>
>>
>> >> Yes, those particular types have initializers that take no arguments.
>> That
>>
>>
>> >> does not address my question. You merely restated your initial
>> observation
>>
>>
>> >> that many types in Swift have implemented `init()`.
>>
>>
>> >>
>>
>>
>> >> I didn't think the value returned by `init()` was regarded as any sort
>> of
>>
>>
>> >> zero--or even any sort of "default." In fact, some types in Foundation
>> have
>>
>>
>> >> a static property called `default` distinct from `init()`. In Rust, the
>>
>>
>> >> Default trait requires a function called `default()`, which is
>> documented
>>
>>
>> >> as being useful when you want "some kind of default value, and don't
>>
>>
>> >> particularly care what it is."
>>
>>
>> >>
>>
>>
>> >> I was asking whether there's some understanding, of which I've been
>>
>>
>> >> unaware, that the result of `init()` (or the equivalent in other
>> languages)
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161226/a73f9c24/attachment.html>


More information about the swift-evolution mailing list