> On Feb 21, 2017, at 11:50 PM, Chris Lattner <[email protected]> wrote: > > On Feb 20, 2017, at 11:12 PM, John McCall <[email protected]> wrote: >>> As you know, I still think that adding typed throws is the right thing to >>> do. I understand your concern about “the feature could be misused” but the >>> same thing is true about many other language features. >> >> That's fair, but I do think there's an important difference here. The way I >> see it, typed-throws is really something of an expert feature, not because >> it's at all difficult to use, but the reverse: because it's easy to use >> without really thinking about the consequences. (And the benefits are >> pretty subtle, too.) I'm not saying that we should design it to be hard to >> use, but I think maybe it shouldn't immediately suggest itself, and it >> especially shouldn't come across as just a more specific version of throws. > > Yeah, I agree that it will be appealing to people who don’t know better, but > here’s the thing: the (almost certain) Swift design will prevent the bad > thing from happening in practice. > > Consider the barriers Swift already puts in place to prevent the bad thing > (declaring an inappropriately narrow explicitly-specified throw signature) > from happening: > > 1) First of all, you need to declare a public API. If it isn’t public, then > there is no concern at all, you can evolve the implementation and clients > together. > > 2) The Second problem depends on the number of errors it can throw. If there > is exactly one type of error, the most common way to handle it is by > returning optional. If you have one obvious failure mode with a value, then > you throw that value. The most common case is where you can throw more than > one sort of error, and therefore have an enum to describe it. > > 3) Third, your enum needs to be declared fragile in order to allow clients to > enumerate their cases specifically. > > The third step (having to mark your enum fragile, however it is spelled) is > the biggest sign that you’re opting into a commitment that you should think > really hard about. If folks don’t know that this is a big API commitment, > then we have bigger problems.
You're imagining somebody adding a throws annotation because their function itself has one or two explicit throw sites. In reality, it's probably because they're calling some other function that can throw. The low-impedence path in that case is to declare that you throw whatever that function throws; this is why people talk about exceptions encoding your library's dependency tree. >>> One thing you didn’t mention is that boxing thrown values in an existential >>> requires allocation in the general case. This may be unacceptable for some >>> classes of Swift application (in the embedded / deep systems space) or >>> simply undesirable because of the performance implication. >> >> So, the performance implication cuts both ways. We can design the ABI for >> typed-throws so that, say, the callee initializes some buffer that's passed >> into it. That's an ABI that will kill some potential allocations in deep >> systems code, no question about it. > > Agreed. > >> But in non-deep-systems code, we generally expect that error types will be >> resilient, which means that there are non-zero dynamic costs for allocating >> space on the stack for the error. > > Proposed solution: ABI is that the callee takes in a register which is > either a buffer address to fill in or null. On error, the callee returns the > error pointer in a specific register. If there was a buffer passed in, it > uses it, otherwise it allocates. > > In practice, this allows the compiler to only pre-allocate the buffer when it > knows the fixed size, otherwise the caller allocates on the heap on demand. > > AFAICT, the cost of this API is only a “li rN, 0” in the normal path. If you're willing to give up on a no-malloc guarantee, even if the fact of resilience, yes, this and similar techniques would work. I'm not sure that all "deep systems" code is quite that deep. John. _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
