> On Mar 16, 2016, at 7:04 AM, Ross O'Brien via swift-evolution > <[email protected]> wrote: > > A question about parsing: one of the perceived disadvantages to 'module' and > 'file' is how easily they might also be used as variable names. How easily > the parser can tell from context whether they're intended as variable names > or as access level keywords is important to deciding whether they're good > choices for access level words, or whether they're better as modifiers (e.g. > 'private(module)' ). Is this a significant concern, or, like argument labels > in function calls, can the compiler handle this? (It seems pretty likely to > me that any accessibility label will be succeeded by > 'class'/'enum'/'struct'/'protocol'/'let'/'var'/'func', but I don't know if > that's enough). > > Also, returning to a point in Chris Lattner's original brief for this > discussion: how should this accessibility work with @testable? > > At the moment, if a unit test file calls "import ModuleName" it has access to > a module's public symbols, but if it calls "@testable import ModuleName" it > has access to internal symbols. I like the idea of maintaining "@testable" so > it's clear which module is being tested regardless of access level, but > should we consider using the access level keywords as an attribute to this in > future? > > e.g. > @testable(public) import ModuleName > @testable(internal) import ModuleName > @testable(file) import ModuleName // lets us test correctness of file-scoped > behaviours
I like this idea, and want this capability. But my first thought is this would be better accomplished by a more fine-grained import capability. That is, the ability to import only certain parts from a module. Not sure that would handle the file case though. > > If this is the case then this would seem clunky: > @testable(private(scope)) import ModuleName > > >> On Wed, Mar 16, 2016 at 10:43 AM, Ilya Belenkiy via swift-evolution >> <[email protected]> wrote: >> The full form would then need to be private(scope). I think that >> private(file, set) would be more consistent with private(set), which would >> then be a shorthand for private(scope, set). >> >>> On Wed, Mar 16, 2016 at 4:18 AM Haravikk via swift-evolution >>> <[email protected]> wrote: >>> I like the idea of repurposing brackets after private to do this. I think >>> though that it might be better if there were also a private(type) option to >>> allow us to be explicit about it, even if we can still type just private to >>> use it by default. >>> >>> About replacing private(set), the examples you’ve given look like computed >>> properties, and being able to put the accessibility declaration before the >>> setter is a good option, but for stored properties I think we also need a >>> way to specify the restriction, for example private(file: set) to enable >>> setting the value only at the file level. This means that private on its >>> own is by default actually private(type: get set) >>> >>> >>>> On 16 Mar 2016, at 06:49, Patrick Pijnappel via swift-evolution >>>> <[email protected]> wrote: >>>> >>> >>>> Ok to summarize: >>>> >>>> Setter access modifiers >>>> var foo: Int { private set { ... } } >>>> var foo: Int { private set } >>>> Consistent with mutating set { ... }. Arguably the current private(set) is >>>> inconsistent. >>>> Eliminates the odd corner case of having a double access modifier, e.g. >>>> public private(set) var foo: Int. >>>> It's very sensible for custom getters/setters (top case), it just requires >>>> allowing a bodiless get/set. We already kinda do this in protocols. >>>> >>>> Access modifier keywords >>>> public/private(module)/private(file)/private >>>> It's not clear from the keywords how restrictive local/private/internal >>>> are, while private(module) and private(file) are obvious. This makes a >>>> declaration either public, or private to a certain scope. Arguably e.g. >>>> public/module/file/declaration has similar benefits but they aren't as >>>> clearly access control related as a keyword (e.g. module could just as >>>> well be declaring a module). >>>> private(module) and private(file) are relatively long, but the longest – >>>> private(module) – is rarely used (outside the standard library) as it's >>>> the default. Most uses of the old private are more appropriately done >>>> using the new private, so private(file) would likely be used less than >>>> private. >>>> The scheme expands very well to named submodules, e.g. if you have a >>>> submodule named model you might limit the scope using private(model). >>>> private(file) as opposed to private-file or private/file makes it more >>>> consistent with the new function-like syntax for e.g. attributes. >>>> >>>>> On Wed, Mar 16, 2016 at 11:26 AM, Ross O'Brien via swift-evolution >>>>> <[email protected]> wrote: >>>>> It's occurring to me, reading these recent posts, that we have two >>>>> orthogonal systems of access levels. >>>>> >>>>> Swift's current access system is file based; a project file decides which >>>>> files comprise a module, and the terms 'public', 'internal' and 'private' >>>>> determine whether a property is accessible to all, accessible only within >>>>> files of the module, or accessible only within a file. (This takes on an >>>>> extra dimension as files may belong to several modules). >>>>> >>>>> The concept which began this discussion, and several of the proposed >>>>> concepts in this discussion, ask instead for a type-based access system >>>>> similar to those in other languages including Objective-C, where >>>>> 'public', 'protected' and 'private' are the terms of choice and they >>>>> restrict access to a type or subtypes. >>>>> >>>>> I think it would be confusing if Swift applied 'public' to a concept in >>>>> the file-based access system and 'private' to a concept in the type-based >>>>> access system. >>>>> >>>>> I would prefer clearer terms which actually mention the restrictions of >>>>> the level. For example, 'inherited', not 'protected', in the case of >>>>> properties accessible by a class and its subclasses; 'declaration', >>>>> rather than 'private' or 'scoped', to refer to properties only accessible >>>>> within a given type or extension declaration. >>>>> >>>>> Since, at the moment, a declaration can only occur within one file, I >>>>> think this most-restricted level has managed to pass as a level of the >>>>> file-based access system. However, if the system is ever extended, we're >>>>> going to run into new syntax decisions where we have 'private module' >>>>> functions (accessible only within the given type in the same module) >>>>> trying to communicate with 'protected file' properties (accessible only >>>>> with the type and its subtypes in the same file), and that might lead to >>>>> conflicts, so perhaps we should decide how those might be declared now. >>>>> >>>>>> On Tue, Mar 15, 2016 at 11:51 PM, Jonathan Hull via swift-evolution >>>>>> <[email protected]> wrote: >>>>>>> On Tue, Mar 15, 2016 at 2:33 PM Erica Sadun <erica at ericasadun.com> >>>>>>> wrote: >>>>>>> And again, moving the access control modification to the end just >>>>>>> doesn't look >>>>>>> right to me or seem to enhance readability. :( >>>>>> I like Shawn’s proposal better for cases where there are custom >>>>>> getter/setter implementations. We should definitely be able to do: >>>>>> >>>>>> var foo:Int { >>>>>> public get {…} >>>>>> private(file) set {…} >>>>>> } >>>>>> >>>>>> In fact, that is what I first tried to do before learning about >>>>>> private(set). But without the implementations, it just seems strange to >>>>>> put the scoping after the rest of the declaration (they work above >>>>>> because they are before the custom getter/setter). >>>>>> >>>>>> I still like the idea of having the option to use parameter-like syntax >>>>>> for cases where you don’t have custom getters/setters: >>>>>> >>>>>> private var foo:Int >>>>>> private(file) var foo:Int >>>>>> private(set: file) var foo:Int >>>>>> private(get: global, set: file) var foo:Int >>>>>> >>>>>> >>>>>> I guess, if we had some way to represent the standard getter/setter, >>>>>> that might work too. I don’t love it, but maybe with better wording? >>>>>> >>>>>> var foo:Int{ >>>>>> public get useDefault >>>>>> private(file) set {…} >>>>>> } >>>>>> >>>>>> Thanks, >>>>>> Jon >>>>>> >>>>>> >>>>>>>> On Mar 14, 2016, at 10:22 PM, Patrick Pijnappel >>>>>>>> <[email protected]> wrote: >>>>>>>> >>>>>>>> I like Shawn's proposal: >>>>>>>> >>>>>>>> var foo: Int { private(file) set } >>>>>>>> >>>>>>>> In fact it's probably more sensible than the current private(set) IMO. >>>>>>> >>>>>>> >>>>>>> For example, we already use >>>>>>> >>>>>>> var foo: Int { mutating get { ... } } >>>>>>> >>>>>>> and not >>>>>>> >>>>>>> mutating(get) var foo: Int { get { ... } } >>>>>>> >>>>>>>> On Tue, Mar 15, 2016 at 4:13 PM, Patrick Pijnappel >>>>>>>> <[email protected]> wrote: >>>>>>>> I like Shawn's proposal: >>>>>>>> >>>>>>>> var foo: Int { private(file) set } >>>>>>>> >>>>>>>> In fact it's probably more sensible than the current private(set) IMO. >>>>>>>> >>>>>>>> >>>>>>>> While I like private(get: file, set: module) idea, I think it just >>>>>>>> gets too inconsistent with private(set: public) and private(set: >>>>>>>> private) (?!) >>>>>>>> >>>>>>>>> On Tue, Mar 15, 2016 at 3:39 PM, Jonathan Hull via swift-evolution >>>>>>>>> <[email protected]> wrote: >>>>>>>>>> On Mar 14, 2016, at 8:36 PM, Patrick Pijnappel via swift-evolution >>>>>>>>>> <swift-evolution at swift.org> wrote: >>>>>>>>>> The only question is (as Sean mentioned) how this combines with the >>>>>>>>>> syntax >>>>>>>>>> for setter access level, e.g. the current private(set). Options: >>>>>>>>>> - Unnamed 2nd argument, giving private(file), private(file, set), >>>>>>>>>> private(set). >>>>>>>>>> - Named 2nd argument, giving e.g. private(file), private(file, >>>>>>>>>> accessor: >>>>>>>>>> set), private(accessor: set). Less ambiguity but longer. >>>>>>>>>> - Not using multiple arguments, but that'd probably break >>>>>>>>>> consistency with >>>>>>>>>> the other unification efforts going on to make everything look like >>>>>>>>>> function calls. >>>>>>>>> What about the following 3 forms? >>>>>>>>> >>>>>>>>> private(file) //both setter and getter have file scope >>>>>>>>> private(set: file) //setter has file scope. Equivalent to current >>>>>>>>> “private(set)" >>>>>>>>> private(get: module, set: file) //getter has module scope & setter >>>>>>>>> has file scope >>>>>>>>> >>>>>>>>> It is a bit weird, but we should probably also allow “public" in that >>>>>>>>> last form: private(get: public, set: module) >>>>>>>>> >>>>>>>>> Thanks, >>>>>>>>> Jon >>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> swift-evolution mailing list >>>>>>>>> [email protected] >>>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> swift-evolution mailing list >>>>>> [email protected] >>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>> >>>>> >>>>> _______________________________________________ >>>>> swift-evolution mailing list >>>>> [email protected] >>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>> >>>> _______________________________________________ >>>> swift-evolution mailing list >>>> [email protected] >>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> _______________________________________________ >>> swift-evolution mailing list >>> [email protected] >>> https://lists.swift.org/mailman/listinfo/swift-evolution >> >> _______________________________________________ >> swift-evolution mailing list >> [email protected] >> https://lists.swift.org/mailman/listinfo/swift-evolution > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
