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

Daniel Leping daniel at crossroadlabs.xyz
Sun Dec 25 22:52:50 CST 2016


Ok, which approach is easier? Plain struct working out of the box or adding
an additional conformance? I like the usage be as easy as possible and as
less effort as possible.

On Mon, 26 Dec 2016 at 10:20 Xiaodi Wu <xiaodi.wu at gmail.com> wrote:

> On Sun, Dec 25, 2016 at 11:46 PM, Daniel Leping <daniel at crossroadlabs.xyz>
> wrote:
>
> You are right, usually it's required to implement a protocol which is not
> a good approach.
>
>
> Why is it not?
>
>
> The best is plain objects which can be used independently of ORM if needed
> (as DTOs, i.e.).
>
>
> An object that conforms to some protocol can still be used independently
> of the ORM solution!
>
> I was thinking of DefaultConstructable as a protocol automatically applied
> to any class/struct having a default init, which is really logical for me.
>
>
>
> 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)
> is expected to be some sort of zero or an identity element. I'm not aware
> of any evidence to that effect. Are you?
>
> > Is the thread that I get by writing `let t = Thread()` some kind of zero
> in any reasonable sense of the word?
>
> DefaultConstructibility makes less sense for types that represent some
> sort of resource but make sense for things that are values. But even in
> this case, Thread() gives you a default value for example if you are
> working with a resizable collection of threads.
>
>
> It gives you something different every time. How can this be squared with
> your stated motivation regarding concepts of zero and concepts of equality?
>
> A better question is why does thread currently implement a default
> constructor?
>
>
> It's an initializer that takes no arguments, because none are needed for a
> new thread. How else would you write it?
>
> > Do you mean to argue that for an integer the additive identity should be
> considered "more prominent and useful" than the multiplicative identity?
> I'm not aware of any mathematical justification for such a conclusion.
>
> I do. The justification is that if I call the default constructor of Int
> currently, I get the value of 0.
>
>
> This is backwards. Why do you believe that the value you obtain from
> `init()` is intended to be an identity element at all, let alone the most
> important one? (It's also circular reasoning. Since `init()` only ever
> gives you one value at a time, by your reasoning it demonstrates that every
> type must have one "more prominent and useful" identity, which is begging
> the question.)
>
> Which means that the binary operation must be addition.
>
>
> Based on the value of `Int.init()`, you conclude that addition of integers
> is a "more prominent and useful" operation than multiplication? Again, this
> is backwards. Rather, we know that each numerical type belongs to multiple
> ring algebras; there is no basis for reckoning any as "more useful." Since
> `init()` can only ever give us one value at a time, we know that `init()`
> cannot give a value that is a meaningful default with respect to any
> particular operation.
>
> If I call String() I get "" which is the identity of the + String
> operation.
>
>
> 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.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161226/652dfe37/attachment.html>


More information about the swift-evolution mailing list