This is a great proposal, I’m a strong supporter, but have one question and one 
strong push back:

> On Oct 2, 2017, at 1:31 PM, Slava Pestov via swift-evolution 
> <swift-evolution@swift.org> wrote:
> Introduction
> We propose introducing an @inlinable attribute which exports the body of a 
> function as part of a module's interface, making it available to the 
> optimizer when referenced from other modules.
> 
The major question I have is “why yet another attribute”.  The thread about 
exhaustive/extensible enums is similarly proposing introducing another one-off 
way to be enums fragile, and this is directly related just for function-like 
things.

I’d love to see rationale in the proposal for why you’re not taking this in one 
of these directions:

1) Why not another level of access control?  There is a reasonable argument 
that what you’re doing is making something “more public than public” or that 
you’re making the “body also public”.  I’m not strongly in favor of this design 
approach, but if you agree, the doc should explain why you’re not in favor of 
it.

2) Why can’t we have a single Swift-wide concept that unifies all of the 
resilience ideas under a single umbrella like “fragile” - which indicates that 
the body of a declaration is knowable to clients?  There is a very reasonable 
holistic design where “fragile public func” makes its body inlinable, and 
“fragile enum” similarly makes the cases knowable to the client (thus making 
exhaustive switching a possibility).  I am strongly in favor of this approach.  


In any case, even if you’re opposed to these approaches, I’d love for the 
“alternatives considered” section to indicate what the objection is.  I am 
really very concerned that you’re causing a keyword/attribute explosion and 
conceptual complexity by adding too many small things to individual parts of 
the language.  We would ideally have a simple and holistic solution to 
resilience.

> Effect on ABI stability
> 
> The introduction of the @inlinable attribute does not change the ABI of 
> existing declarations. However, adding @inlinable to an existing declaration 
> changes ABI, because the declaration will no longer have a public entry point 
> in the generated library. Removing @inlinable from an existing declaration 
> does not change ABI, because it merely introduces a new public symbol in the 
> generated library.
> 
This semantic doesn’t make sense to me, and I think we need to change it.  I 
think we are better served with the semantics of “the body may be inlined, but 
doesn’t have to.”  This corresponds to available_externally linkage in LLVM, 
<http://llvm.org/docs/LangRef.html#linkage-types> and is provided by GNU89 
"extern inline".

Here are 5 reasons:

1) the current spelling: "@inlinable” implies that the body “may” be inlined, 
not that it “must” be inlined.

2) there are lots of reasons why the compiler may not *want* to inline the body 
of a declaration, including wanting fast debug builds, “optimizing for size” 
builds, or cost heuristics that lead the compiler to believe that there is no 
gain for inlining the body of a function in some context.

3) If the symbol is always guaranteed to be present, adding @inlinable is an 
ABI preserving change.  I think that this is also really important because it 
reflects a natural evolution of code: in R1 of a module’s public release, a 
symbol my be public, but after numerous releases, it may be decided that it is 
stable enough to make “inlinable”.

4) Certain declarations *have* to be emitted anyway, e.g. an @inlinable open 
method on a class can’t actually be inlined in most cases, because the call is 
dynamicly dispatched.
> We have discussed adding a "versioned @inlinable" variant that preserves the 
> public entry point for older clients, while making the declaration inlinable 
> for newer clients. This will likely be a separate proposal and discussion.
> 
5) It eliminates this complexity.


> Comparison with other languages
> The closest language feature to the @inlinable attribute is found in C and 
> C++. In C and C++, the concept of a header file is similar to Swift's binary 
> swiftmodule files, except they are written by hand and not generated by the 
> compiler. Swift's public declarations are roughly analogous to declarations 
> whose prototypes appear in a header file.
> 
> Header files mostly contain declarations without bodies, but can also declare 
> static inlinefunctions with bodies. Such functions are not part of the binary 
> interface of the library, and are instead emitted into client code when 
> referenced. As with @inlinable declarations, static inlinefunctions can only 
> reference other "public" declarations, that is, those that are defined in 
> other header files.
> 
The writing should be clarified, because there are multiple concepts going on 
here, including GNU89’s notion of inline, C99’s notion of inline (aka extern 
inline), and static inline, each with overlapping but and confusingly different 
semantics.

-Chris


_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to