[swift-evolution] Proposal: Re-instate mandatory self for accessing instance properties and functions

Marc Knaup marc at knaup.koeln
Sun Dec 13 10:02:20 CST 2015


I don't think (Objective-)C styling guides apply to Swift and they
shouldn't.

It's true a lot of existing MacOS/iOS API is using uppercase for global
functions but that's mostly because there weren't many different options at
that time and in that language. They will likely be improved or replaced
over time.

https://developer.apple.com/library/mac/documentation/Swift/Reference/Swift_StandardLibrary_Functions/index.html
I won't like to see all these global functions start uppercase instead.

Btw your example should read UIGraphics.currentContext instead. It's part
of UIKit, not Core Graphics.
But yes, that's the best way to fix it instead of relying on uppercase
letters.
The global namespace should have as little functions and variables as
possible anyway.


On Sun, Dec 13, 2015 at 4:51 PM, ilya <ilya.nikokoshev at gmail.com> wrote:

> > I'd find it horrible when global variables & functions would suddenly
> start with an uppercase letter.
>
> Uhm, that's part of the style guide for existing C- and
> Objective-C-functions, and by extension in current Swift apps, that target
> iOS.
>
> They are of course ugly, and the best way to get rid of those is to move
> gradually all of the free functions and constants into types. And then
> those names will be accessible via the UpperCaseType.lowerCaseSomething
> convention. Hopefully Apple does that to the system framworks as well:
>
> CGContextRef UIGraphicsGetCurrentContext() -> CGContext.currentContext
>
> etc.
>
>
> On Sun, Dec 13, 2015 at 6:38 PM, Marc Knaup <marc at knaup.koeln> wrote:
>
>> I'd find it horrible when global variables & functions would suddenly
>> start with an uppercase letter.
>> Right now the distinction is VERY clear: Types start uppercase, anything
>> else lowercase.
>> It should stay that way and the compiler should warn about violations
>> there.
>> As mentioned earlier the IDE can easily help with the distinction between
>> global and non-global symbols anyway.
>>
>> Enum cases are still a problem here since they are values but start
>> uppercase. But I'm working on a proposal which covers that too.
>>
>> In any case that's an unrelated topic and should be discussed separately.
>>
>> On Sun, Dec 13, 2015 at 4:32 PM, David Hart via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>>> For the record I would also like it if the "globals must start with an
>>> uppercase letter" rule were enforced by the compiler (well, not in the
>>> playground, those aren't true globals).
>>>
>>>
>>> +1, in the same vein, global a should stand out :)
>>>
>>> On 13 Dec 2015, at 11:35, ilya <ilya.nikokoshev at gmail.com> wrote:
>>>
>>> > It might seem obvious in a small piece of code like yours, but it
>>> becomes less so in a class several hundred of lines long.
>>>
>>> I'll be happy to take a look at the specific examples and see if perhaps
>>> self-dot access will be useful there.
>>> But even if we disagree you're still able to use self-dot access in any
>>> place where you feel this to be beneficial without any changes in the
>>> language.
>>>
>>> > Why use a style guide when the language can enforce rules to eliminate
>>> the ambiguity?
>>>
>>> Because each project's situation can be unique. For the same reason
>>> there's no need to rush to add concurrency at the language level without
>>> considering other possibilities first.
>>>
>>> For the record I would also like it if the "globals must start with an
>>> uppercase letter" rule were enforced by the compiler (well, not in the
>>> playground, those aren't true globals).
>>>
>>> It still looks to me that if we make compiler enforce that and the
>>> "instance names must not start with an uppercase letter" rule this
>>> eliminates the ambiguity discussed in this thread.
>>>
>>> On Sun, Dec 13, 2015 at 13:12 David Hart <david at hartbit.com> wrote:
>>>
>>>> struct Vector {
>>>>     var dx: Double
>>>>     var dy: Double
>>>>     var length: Double { return sqrt(dx*dx + dy*dy) }
>>>> }
>>>>
>>>> vs
>>>>
>>>> struct Vector {
>>>>     var dx: Double
>>>>     var dy: Double
>>>>     var length: Double { return sqrt(@dx*@dx + @dy*@dy) }
>>>> }
>>>>
>>>> struct Vector {
>>>>     var dx: Double
>>>>     var dy: Double
>>>>     var length: Double { return sqrt(self.dx*self.dx + self.dy*self.dy)
>>>> }
>>>> }
>>>>
>>>>
>>>> I don't agree with you because when reading your first example, I have
>>>> to make a mental gymnastic to find out if the variables are local/global
>>>> variables or if they are instance properties. It might seem obvious in a
>>>> small piece of code like yours, but it becomes less so in a class several
>>>> hundred of lines long.
>>>>
>>>> On 13 Dec 2015, at 10:48, ilya <ilya.nikokoshev at gmail.com> wrote:
>>>>
>>>> > For me, readability has always been more important, as we spend most
>>>> of our time reading than writing code.
>>>> Agree.
>>>>
>>>> > but they make code editing easier at the expense of readability.
>>>> Disagree. This really depends on the example. E.g. which is more
>>>> readable:
>>>>
>>>> struct Vector {
>>>>     var dx: Double
>>>>     var dy: Double
>>>>     var length: Double { return sqrt(dx*dx + dy*dy) }
>>>> }
>>>>
>>>> vs
>>>>
>>>> struct Vector {
>>>>     var dx: Double
>>>>     var dy: Double
>>>>     var length: Double { return sqrt(@dx*@dx + @dy*@dy) }
>>>> }
>>>>
>>>> struct Vector {
>>>>     var dx: Double
>>>>     var dy: Double
>>>>     var length: Double { return sqrt(self.dx*self.dx + self.dy*self.dy)
>>>> }
>>>> }
>>>>
>>>>
>>>>
>>>> On Sun, Dec 13, 2015 at 12:40 PM, David Hart <david at hartbit.com> wrote:
>>>>
>>>>> Hi Ilya,
>>>>>
>>>>> Why use a style guide when the language can enforce rules to eliminate
>>>>> the ambiguity?
>>>>>
>>>>> On the other hand, it allows a logical explanation of how you can take
>>>>> code from global scope and put it into an instance scope
>>>>>
>>>>>
>>>>> This helps implementing patterns like "take a long function and make
>>>>> it into a struct with a bunch of small functions instead".
>>>>>
>>>>>
>>>>> Both of your previous points make sense but they make code editing
>>>>> easier at the expense of readability. For me, readability has always been
>>>>> more important, as we spend most of our time reading than writing code.
>>>>>
>>>>> That's why I suggest using .x and .f() to mark implicit self.
>>>>>>
>>>>>
>>>>> I agree that that would potentially add confusion to the grammar. I've
>>>>> always liked the @ and @@ prefixes of Ruby for accessing instance and class
>>>>> properties, but I agree that symbols like that would feel a bit foreign in
>>>>> Swift.
>>>>>
>>>>> David
>>>>>
>>>>> On 13 Dec 2015, at 10:16, ilya via swift-evolution <
>>>>> swift-evolution at swift.org> wrote:
>>>>>
>>>>> > But implicit self is confusing in a lot of code
>>>>>
>>>>> On the other hand, it allows a logical explanation of how you can take
>>>>> code from global scope and put it into an instance scope:
>>>>>
>>>>> let greeting = "Hello"
>>>>> let name = "Michael"
>>>>>
>>>>> func greet() {
>>>>>     print("\(greeting), \(name)")
>>>>> }
>>>>>
>>>>> seemlessly becomes
>>>>>
>>>>> class Greeter {
>>>>>
>>>>>     let greeting = "Hello"
>>>>>     let name = "Michael"
>>>>>
>>>>>     func greet() {
>>>>>         print("\(greeting), \(name)")
>>>>>     }
>>>>>
>>>>> }
>>>>>
>>>>> > can (and does) lead to shadowing bugs,
>>>>>
>>>>> There are simple strategies that help to minimize the amount of
>>>>> shadowing, e.g.
>>>>>
>>>>> - only expose the minimum necessary amount of names in any scope
>>>>> - break functions into small part so that it's easy to see all the
>>>>> local name declarations
>>>>> - not use any globals, or at least name them in a visually different
>>>>> way (UppercaseCamelStyle)
>>>>> - name properties and locals in a different way (classProperty,
>>>>> local_var)
>>>>>
>>>>> Even without a formal code style, if you tend to make property names
>>>>> longer and local names shorter, your risk of shadowing goes down.
>>>>>
>>>>> > .x and .f() to mark implicit self. I realize that this may conflict
>>>>> with enum usage.
>>>>>
>>>>> This will lead to a lot of ambiguity:
>>>>>
>>>>> func f() {
>>>>>     let x = NSOperation()
>>>>>     .name = "Name" // is it x.name or self.name??
>>>>>    ...
>>>>> }
>>>>>
>>>>> >  If so, then use another marker. For instance :x or ^x or anything.
>>>>>
>>>>> This is workable, but still I think this is one of the best points of
>>>>> Swift – the existence of instance scope where names are simply written
>>>>> as-is. This helps implementing patterns like "take a long function and make
>>>>> it into a struct with a bunch of small functions instead".
>>>>>
>>>>> > is very difficult to reason about in diffs or any other interface
>>>>> that isn't an IDE (especially code review)
>>>>>
>>>>> This is the point where I entirely agree, good code should be easily
>>>>> read in any context.
>>>>> Again, may I suggest you take a look into using a style guide to
>>>>> differentiate visually between local and instance scope?
>>>>>
>>>>> Ilya
>>>>>
>>>>> On Sun, Dec 13, 2015 at 10:15 AM, Rob Napier via swift-evolution <
>>>>> swift-evolution at swift.org> wrote:
>>>>>
>>>>>> I wanted to reopen this discussion that seems to have trailed off.
>>>>>> Requesting the return of self was my very first ask of Swift if I remember
>>>>>> correctly (https://devforums.apple.com/message/1013085). Continued
>>>>>> work in Swift has both strengthened and modified that ask. Here are several
>>>>>> of the examples discussed before:
>>>>>>
>>>>>> https://gist.github.com/schwa/94b11dc0a7a331f46b25
>>>>>> https://gist.github.com/rnapier/478465d1b15e95b98b42
>>>>>> https://gist.github.com/rnapier/4213dc64206b17df6935
>>>>>> https://gist.github.com/dwineman/d6c56ec0c0e2fdb761db
>>>>>>
>>>>>> I get that it seems tedious to type (and read) "self." and I get that
>>>>>> "self." is currently a hint that self might be captured (but doesn't
>>>>>> actually mean that, since you can use self. without capturing, and
>>>>>> sometimes have to, very often in init, so really it's basically meaningless
>>>>>> for that use).
>>>>>>
>>>>>> That's why I suggest using .x and .f() to mark implicit self. I
>>>>>> realize that this may conflict with enum usage. If so, then use another
>>>>>> marker. For instance :x or ^x or anything. But implicit self is confusing
>>>>>> in a lot of code, can (and does) lead to shadowing bugs, and is very
>>>>>> difficult to reason about in diffs or any other interface that isn't an IDE
>>>>>> (especially code review).
>>>>>>
>>>>>> Thoughts, David? I agree with your basic proposal; I just want to
>>>>>> amend it.
>>>>>>
>>>>>> -Rob
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> swift-evolution mailing list
>>>>>> swift-evolution at swift.org
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>>
>>>>>>
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution at swift.org
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>
>>>>>
>>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151213/745b0266/attachment.html>


More information about the swift-evolution mailing list