I agree with that. Having @inlinable and @inlineAvailable would be very confusing.
If I were to choose between the proposed spellings, I would go with either @availableFromInlinable or @usableFromInlinable because these attributes actually make it very clear what they're doing.
If we'd go that way, first thing that comes to mind is:
@hidden public
Or in case we keep the base access level 'internal', some other suggestions:
@exposed
@externAvailable
@binaryAvailable
@externCallable
@binaryCallable
I think these describe more accurately what is happening, like @abiPublic, instead of trying to connect this functionality with @inlinable. Perhaps in the future other features will need the same functionality where something like @inlineAvailable wouldn't make sense.
Personally I like @exposed, but an attribute on public might make sense as well.
To me this is the one that makes most sense. The declaration is hidden from view by the language when in another module, but remains accessible externally for inlining. With regard to library evolution it has to obey the same rules as public because of this external exposure.
I could also envision the possibility of removing @hidden from a function in version 2 of a library and backdating the availability to version 1. It should work since the symbol was made available to the dynamic linker the whole time. @hidden public is self-explanatory in that situation.
Iām just realizing that I had missed part of the conversation that was collapsed under an [ā¦] ā Iāll quote it below, since others might have missed it too:
Continuing my thoughts on @hidden public... it also changes things a bit more than the other attributes. Take this example from the proposal:
public class C {
@abiPublic internal class D {
@abiPublic internal func f() {}
}
}
Because @abiPublic modifies internal by promoting it to something like "semi-public", members inside of class D must be declared @abiPublic in order to be accessible too..
Whereas with @hidden public we are demoting public to "semi-public". Because the members can't be more public than the enclosing class, the public members automatically become "semi-public". This results in less boilerplate:
public class C {
@hidden public class D {
public func f() {}
}
}
I can see this as both a good and a bad thing. A modifier to internal is better if you want everything to have to be labeled explicitly with the new attribute, whereas a modifier to public is better if you want to be able to write @hidden only once for the whole type.
I guess we could also work this out by adding a new semipublic access level instead of piling up a modifier on top of an existing access level.
I completely missed this proposal, but if it's not too late, I'd like to ask if @abiPublic could be allowed for private/fileprivate members, too?
The proposal states: "The @abiPublic attribute does not affect source-level visibility of a declaration". IMO, that means that it should also not depend on the source-level visibility of a declaration. To the external module, there is effectively no difference between internal and private; it's only about creating good in-module interfaces. @abiPublic is an orthogonal concern to source-level visibility.
Re-reading this thread, I was struct by this comment from @Slava_Pestov, just as @jdhealy was. I believe this is a really good reason not to name this as @inlinable. I think there would be a tendency for a naive user to believe it made the routine inlinable within a module, something on which it has absolutely no bearing.
I'm still thinking about naming, but one idea is to prefix both of these attributes with something that really expresses the cross-module usage.
Maybe: @xmodInlinable and @xmodBackdoor. (@xmodBackDoor?)
The "@abiPublic" idea is pretty obscure, so I think that inventing a term like backdoor that is new, but that really makes sense in the terms of what the attribute implies, has a lot of validity.
Karl, the reason that this is not feasible has been covered during review. In brief, private symbols are not uniquely mangled (each file could theoretically have an identically named fileprivate extension method for the same type, for example), and @abiPublic symbols need to be effectively public under the hood, so they require unique mangling.
Why not use @frozen? Rather than being on a type, it could also be on a member.
I find terms like abiPublic or even inlineable are very literal and technical, but not all that expressive in your code. The great thing about frozen is that it's framed in terms of what you can(not) edit in this source file.
public class ABC {
@frozen internal var value: Int
@inlineable
public func pickANumber() -> Int { return value * 2 }
}
I'm imagining errors like "you can only inline accesses to @frozen members", and I think it sounds really nice.
I like @exposed as well. It has the right base meaning and also the word has the right connotations of something being seen but also something not supposed to be public.
I think all the spellings that contain words like "visible" / "available" / "inline" just add to the confusion because those words all have pre-existing meanings for Swift and it's too hard to make the distinction from the existing meaning without confusion or a hugelyLongAttributeName. Thus an entirely unrelated word is the way to go, I think.
@exposed and @frozen seem like great directions, but they should also imply that this has little to no bearing on actually using the functions, but instead how they're optimized. Perhaps something like @optimized(exposed) and @optimized(frozen)?
someone higher up please answer this but could it be the case where marking a function inlineable or frozen can actually harm performance if it contains multiple calls to other internal functions, because now all of a sudden there are multiple entry points to jump through instead of just one
The analogy is imperfect, though, and I think potentially misleading. When an enum is frozen, you canāt change stuff inside the braces. When a function is āABI public,ā only the stuff outside the braces canāt be changed.
The closest thing to ā@frozenā here, in my view, is whatās now called ā@inlinableā.