Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Toady
Jan 12, 2009

Kallikrates posted:

I also think the point examples are a little too simplistic as lord funk shows. We're told to remove as much redundant type info and rely on inference as much as possible.

string.writeTo(filePath, atomically: ...)

Scanning that code 6 moths from now I am definitely not going to remember if filePath was a URI or String. If I have to fall back to hungarian notation-ish I think readability/scannability has suffered. This proposal asks more from callers in terms variable length/descriptiveness (stuff we write) in order to trim API verbosity: stuff xcode and or auto completes writes for us.

The current style doesn't tell you the type of filePath either. However, alt-clicking the variable in Xcode will show you its type. The argument about not knowing what type a variable is has always felt contrived to me.

Adbot
ADBOT LOVES YOU

Kallikrates
Jul 7, 2002
Pro Lurker
I didn't say I liked the current style either: the first parameter having different rules always struck me as weird and throughout code i've written in the last two years I have cases of func doesAThing(_ typishName: Type) usually because dropping the first param in some cases made for a weirder or ambiguous call site. If I am clicking into statements in the code I am reading, I have moved passed the scanning/looking phase of code reading.

Fully in swift land and from the mailing list - this has already exposed some weird style things especially when the first label has/had default arguments. Where the new first label (previously second but first's default arguments where not override) is required.

Whichever way this proposal goes, I think supporting optional first parameters should also be looked at.

The proposal PR's mostly already look like this:

func moveTo(point point: CGPoint) Removing the special case allows func moveTo(point: CGPoint)

This conversation might be conflating two separate things
1. Better Swityier bridged API //sure great
2. The weird first parameter rule
The first is highlighting the second and maybe after reading enough stuttering definitions we can do something about #2.

Toady
Jan 12, 2009

squidgee posted:

Right - this change just trades one kind of verbosity for another. Instead of writeToURL(filePath), I'll have code that looks like writeTo(filePathString) or writeTo(filePathURL) or whatever. Then, because this naming pattern is totally optional, I'll inevitably forget to use it at some point and write stuff that's confusing to re-read later.

The existing verbose method names save me from myself, and make unfamiliar APIs and codebases easier to navigate, even if they can be annoying at times.

Many Cocoa APIs don't describe types in their selectors. What does -compare: compare to? What type of suffix does -hasSuffix: take? What does -executeFetchRequest:error: return? In Swift, we already leave off type information most of the time when declaring constants and variables, and Xcode can not only supply this information but take you to declarations on cmd-click, so I think this argument feels contrived. Other arguments against the change exist, but this one doesn't feel persuasive to me.

Toady fucked around with this message at 18:47 on Jan 31, 2016

Doctor w-rw-rw-
Jun 24, 2008
Like I already said, cmd-clicking doesn't mean much to me when I'm scanning a lot of code. This is shaving redundancy for redundancy's sake, and for the same amount of clarity forces the developer to write better variable names. Which doesn't scale to situations when you're reading someone else's lovely code.

Forcing the developer to choose between an inline constructor or well-named variables means that the language is now constrained at an API level to disallow implicit conversions at any point in the future lest the deleted context cause usage of an API to ambiguous or otherwise very opaque to the developer when debugging.

To make this concrete, for example, let's say syntax like "addLineTo((100,100))" were under consideration. Now let's say there were two methods, addLineToPoint: and addLineToSize:. "addLineTo((100,100))" would be ambiguous, whereas "addLine(toPoint:(100,100))" and "addLine(toSize:(100,100))" wouldn't, and what's more, would clearly distinguish between the different methods. So, of course, this would constrain the language because two previously different methods would now appear as overloads.

So, something with -[B fooWithNumber:(int32_t)], -[A fooWithString:(NSString *)], and -[A fooWithAny:(id)] might get translated as::
Swift code:
class A {
    func foo(any: AnyObject) -> String {
        return "A.foo - any: \(any)"
    }

    func foo(string: String) -> String {
        return "A.foo - string: \(string)"
    }
}

class B: A {
    func foo(number: Int32) -> String {
        return "B.foo - Int32: \(number)"
    }
}

A().foo(A())
A().foo("asdf")
B().foo("qwer")
B().foo(1)
B().foo(Int32(1))
outputs
code:
"A.foo - any: A"
"A.foo - string: asdf"
"A.foo - string: qwer"
"A.foo - any: 1"
"B.foo - Int32: 1"
Which is dumb, because now that you lack the name as context, you're boned and have to add redundancy back again anyways ("Int32(1)"), only now it's uglier and more prone to error.

Unless I've made a mistake in my reasoning, which is totally possible, I think this would be an annoying change that introduced annoying bugs. It's nonsense. It gives little and takes a lot away.

Toady
Jan 12, 2009

But your example is deliberately using the non-descriptive method name foo, so naturally it's confusing and lacking in context. I'm fine with edge cases like Int32(1) standing out with an initializer because explicitly sized integers are rare/discouraged in Swift. Such a method would likely only accept Int arguments and leave it to clients of the API to convert any weird fixed width integers they're using for some reason.

I don't understand what you mean with the tuple-based addLineTo((100,100)) example, since my understanding is that the translation will be like this:

code:
addLineTo(CGPoint(x: 100, y: 100))
Developers should already be using descriptive variable names like filePath, cursorPoint, boxSize, etc. so I just don't find the argument about variable names convincing. Bad variable names in lovely code would be a problem regardless of this change. I feel like there are valid arguments to be made against the API changes but that people are focusing on trivial or contrived examples to make their case.

Toady fucked around with this message at 20:52 on Jan 31, 2016

Doctor w-rw-rw-
Jun 24, 2008

Toady posted:

I don't understand what you mean with the tuple-based addLineTo((100,100)) example, since my understanding is that the translation will be like this:
I'm saying it removes the possibility of other changes in the language, i.e. if it can deduce the type of the argument, it could elide the redundant type name. It was a what-if example to illustrate a tradeoff.

Toady posted:

But your example is deliberately using the non-descriptive method name foo, so of course it's confusing. I'm fine with edge cases like Int32(1) standing out with an initializer since explicitly sized integers are rare/discouraged in Swift, and you'd already have to explicitly specify the type when initializing such a variable or constant with a literal value.
The method name was built to not distract from the problem, which was that it makes stupidly ambiguous situations far easier to create. Take the previous example and replace class A's definition with
code:
class A {
    func foo(string: String) -> String {
        return "A.foo - string: \(string)"
    }
}

extension A {
    func foo(any: AnyObject) -> String {
        return "A.foo - any: \(any)"
    }
}
Now the method resolves differently, even though class A's interface barely changed; it just got shuffled. Simply because there's no word as context, an entirely different code path was taken in a way that is really easy for a developer to miss unless they really understand the system.

Hell, yesterday I had to step in after a pair of people writing Python struggled to realize that keyword args must come after positional args for 15-30 minutes. If they can get tripped up by something that simple in a language like Python, when they run into stuff like this? Yeah...

Programmers will *definitely* run into it and waste time, and it's not only avoidable it's currently avoided.

Toady
Jan 12, 2009

I just don't see Cocoa or any reasonably-designed API running into that situation, especially Swift-specific frameworks that avoid AnyObject entirely.

Doctor w-rw-rw-
Jun 24, 2008
You're focusing on the wrong thing. It doesn't require AnyObject.

Swift code:
class SuperType { }

class SubType : SuperType { }


class A { }
extension A {
    func foo(superType: SuperType) -> String {
        return "A.foo(SuperType): \(superType)"
    }
}

class B: A {
    func foo(subType: SubType) -> String { // Not an override
        return "B.foo(SubType): \(subType)"
    }
}

A().foo(SuperType())
B().foo(SubType()) // still works if B.foo is deleted, easily avoidable with names
                   // (assuming the methods are meant to do something different)
B().foo(SubType() as SuperType) // Different method called, equivalent to...
B().foo(SuperType())
A().foo(SubType())
outputs
code:
A.foo(SuperType): SuperType
B.foo(SubType): SubType
A.foo(SuperType): SubType
A.foo(SuperType): SuperType
A.foo(SuperType): SubType
"A reasonably-designed API" is incredibly optimistic. This opens a big fat :can:, and shortening the API methods makes it incredibly easy to screw things up. I'm writing code that already compiles, and managing to shoot myself in the foot. Now imagine giving sidearms to every single bridged API and saying "as long as you don't point this at your foot, you'll be fine". It's going to result in way more bleeding feet than necessary.

It barely matters that the examples are slightly contrived, IMO, because it's still not a hard problem to stumble across, and trivially avoidable at that.

EDIT: line break in comment in code

Doctor w-rw-rw- fucked around with this message at 21:28 on Jan 31, 2016

ultramiraculous
Nov 12, 2003

"No..."
Grimey Drawer

squidgee posted:

Right - this change just trades one kind of verbosity for another. Instead of writeToURL(filePath), I'll have code that looks like writeTo(filePathString) or writeTo(filePathURL) or whatever. Then, because this naming pattern is totally optional, I'll inevitably forget to use it at some point and write stuff that's confusing to re-read later.

This is an incredibly contrived example. How often is the variable/parameter declared so far away from its use that it isn't still on screen, and how often does it really matter what the type of the parameter is if the type system says it checks out? If the API does something wildly different/unexpected if you call an overloaded method with an acceptable type, then it's a bad API.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

ultramiraculous posted:

How often is the variable/parameter declared so far away from its use that it isn't still on screen

Pretty often, if the variable in question is a member of a structure.

nah thanks
Jun 18, 2004

Take me out.

ultramiraculous posted:

This is an incredibly contrived example. How often is the variable/parameter declared so far away from its use that it isn't still on screen, and how often does it really matter what the type of the parameter is if the type system says it checks out? If the API does something wildly different/unexpected if you call an overloaded method with an acceptable type, then it's a bad API.

Look, I agree that in many instances this change won't make a huge difference. However, you're underestimating how often code will be less readable because of it, and I'd personally prefer that the language err on the side of clarity over brevity. I don't understand why you'd want to save a few (autocompleted) keystrokes at the expense of readability and source compatibility.

Also, I'd be remiss if I didn't point out that we've all just spent several pages bike shedding. :v:

lord funk
Feb 16, 2004

code:
let content = listItemView.text.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
code:
let content = listItemView.text.trimming(.whitespaceAndNewlines)
'trimming'? I can't think of the last time I saw a gerund as a method name.

Looking at that second line, I realize how much I've learned from autocomplete + method names from Obj-C, and how the new 'Swifty' way wouldn't have helped at all. All sorts of cool stuff pops up when you type 'stringBy,' but 'trimming' doesn't mean anything at all.

nah thanks
Jun 18, 2004

Take me out.

lord funk posted:

Looking at that second line, I realize how much I've learned from autocomplete + method names from Obj-C, and how the new 'Swifty' way wouldn't have helped at all. All sorts of cool stuff pops up when you type 'stringBy,' but 'trimming' doesn't mean anything at all.

This is an important point. I can't tell you how much of Cocoa I've picked up over the years from autocomplete and verbose method names. If there is a move to more abbreviated method names, I hope that's taken into consideration when translating them. :)

nah thanks fucked around with this message at 21:47 on Jan 31, 2016

lord funk
Feb 16, 2004

squidgee posted:

I hope that's taken into consideration when translating them. :)

I'm not hopeful, since whoever is writing up the Obj-C -> Swift translation doesn't seem to see any use for those words they're removing:

https://github.com/apple/swift-evolution/blob/master/proposals/0005-objective-c-name-translation.md posted:

Omit Needless Words

lord funk fucked around with this message at 21:58 on Jan 31, 2016

Doctor w-rw-rw-
Jun 24, 2008
Swift code:
//: Playground - noun: a place where people can play

class SuperType { }
class SubType : SuperType { }
class OtherSubType : SuperType { }

class A { }

// Declared far away from classes A or B
extension A {
    func doSomething(general: SuperType) -> String {
        return "A.doSomething(general): \(general)"
    }
}

class B: A {
    // Marking as override impossible, because it's not an override
    func doSomething(specific: SubType) -> String {
        return "B.doSomething(specific): \(specific)"
    }
}

// -----

// This scenario seems pretty easily possible:
let someFunctionReturnedMe: SuperType = SubType() // Function returns one of the subclasses
B().doSomething(someFunctionReturnedMe)
// Outputs "A.foo(general): SubType"

let someVar = SubType()
B().doSomething(someVar)
// Outputs "B.foo(specific): SubType"

// Oops! Because of how we declared the variable, it resolved the ambiguity differently!
// If only we could avoid this with an obviously named API method.

// -----

// In case it's useful, a reference of what happens:
// 1. A with OtherSubType calls A.doSomething
A().doSomething(OtherSubType())
// Outputs "A.doSomething(general): OtherSubType"

// 2. A with SubType calls A.doSomething
A().doSomething(SubType())
// Outputs "A.doSomething(general): SubType"

// 3. B with SubType calls B.doSomething
// Still works if B.doSomething is deleted – calls non-override A.doSomething
B().doSomething(SubType())
// Outputs "B.doSomething(specific): SubType"

// 4. B with SubType and cast calls A.doSomething
B().doSomething(SubType() as SuperType)
// Outputs "A.doSomething(general): SubType"

// 5. B with OtherSubType calls A.doSomething
B().doSomething(OtherSubType())
// Outputs "A.doSomething(general): OtherSubType"
Spent some time revising my example. Hopefully this better illustrates a couple of ways in which it's problematic.

squidgee posted:

Also, I'd be remiss if I didn't point out that we've all just spent several pages bike shedding. :v:
Hey, I've been writing code to try to demonstrate ways in which it obstructs unambiguous code inspection, which, as writers of code, we also constantly do (reading code)

Toady
Jan 12, 2009

Doctor w-rw-rw- posted:

You're focusing on the wrong thing. It doesn't require AnyObject.

...

"A reasonably-designed API" is incredibly optimistic. This opens a big fat :can:, and shortening the API methods makes it incredibly easy to screw things up. I'm writing code that already compiles, and managing to shoot myself in the foot. Now imagine giving sidearms to every single bridged API and saying "as long as you don't point this at your foot, you'll be fine" is going to result in way more bleeding feet than necessary.

It barely matters that the examples are slightly contrived, IMO, because it's still not a hard problem to stumble across, and trivially avoidable at that.

Overload gotchas are a known quirk--what I was getting at with regards to APIs that avoid AnyObject was the convention of using a protocol type, though overloads can still be introduced via extensions and subclasses (at least until final is default). At that point, I still don't see people's bad decisions as a strike against the style change.

squidgee posted:

Also, I'd be remiss if I didn't point out that we've all just spent several pages bike shedding. :v:

It's not really bike shedding because it's a non-trivial change with potentially large repercussions that are interesting to discuss in a less formal setting than the mailing list.

Toady fucked around with this message at 23:00 on Jan 31, 2016

lord funk
Feb 16, 2004

Toady could you give some examples of how this will make things better? I'm willing to admit that maybe the examples so far have been weak, so if there's some good stuff I'm missing, I'd love to see it.

Doctor w-rw-rw-
Jun 24, 2008

Toady posted:

Overload gotchas are a known quirk--what I was getting at with regards to APIs that avoid AnyObject was the convention of using a protocol type, though overloads can still be introduced via extensions and subclasses (at least until final is default). At that point, I still don't see people's bad decisions as a strike against the style change.

It's less reasonable when a perfectly understandable Objective-C API turns into a Swift equivalent with gotchas, and even if I don't write bad code, I still have to expect it, and now that there could be gotchas I can't see immediately on code inspection, the change creates vastly more opportunities for me to fail to detect bugs.

Toady
Jan 12, 2009

lord funk posted:

Toady could you give some examples of how this will make things better? I'm willing to admit that maybe the examples so far have been weak, so if there's some good stuff I'm missing, I'd love to see it.

If you don't agree with Apple's proposal, I doubt my opinions would be persuasive. Objective-C's verbose style has its roots in an era when all objects were id and methods returned self by default. Restating the types enforced by the Swift compiler feels anachronistic. In imagining these APIs as if they been written for Swift instead of imported from Objective-C, it's hard to picture them being as verbose as they are now. Note that exceptions are made for potentially vague call sites.

The argument has a subjective element; the proposal's examples feel more "Swift-like" to me. However, there have been calls for a more concise API for a long time. John Siracusa once singled out -componentsSeparatedByString: and compared it to what's more commonly known as split() in other languages. To use an example from the proposal:
code:
let content = listItemView.text.stringByTrimmingCharactersInSet(
    NSCharacterSet.whitespaceAndNewlineCharacterSet())
let content = listItemView.text.trimming(.whitespaceAndNewlines)
To me, no clarity is lost in the second form, and it's more readable. From a pedagogical perspective, the shorter form is less intimidating, easier to present, and simpler to read and write.

I'm also biased by accessibility needs. I experience visual snow and ghosting, and big chunks of verbose Cocoa code are irritating to read through, especially after working in concise languages with more whitespace.

Doctor w-rw-rw-
Jun 24, 2008

Toady posted:

Objective-C's verbose style has its roots in an era when all objects were id and methods returned self by default.
The message passing syntax has its roots more in Smalltalk than old limitations, though.

Toady posted:

Restating the types enforced by the Swift compiler feels anachronistic. In imagining these APIs as if they been written for Swift instead of imported from Objective-C, it's hard to picture them being as verbose as they are now. Note that exceptions are made for potentially vague call sites.
They don't feel anachronistic at all. They're more textually clear and yeah, maybe that's because the used to need to be. Is there duplication in syntax along with type metadata? Sure. Do I want to be constantly figuring out that type metadata in my head while reading code? Hell no. That's unproductive and tiring.

Toady posted:

The argument has a subjective element; the proposal's examples feel more "Swift-like" to me. However, there have been calls for a more concise API for a long time. John Siracusa once singled out -componentsSeparatedByString: and compared it to what's more commonly known as split() in other languages. To use an example from the proposal:
code:
let content = listItemView.text.stringByTrimmingCharactersInSet(
    NSCharacterSet.whitespaceAndNewlineCharacterSet())
let content = listItemView.text.trimming(.whitespaceAndNewlines)
To me, no clarity is lost in the second form, and it's more readable. From a pedagogical perspective, the shorter form is less intimidating, easier to present, and simpler to read and write.
Having taught programming before, the idea that the greater character count is more intimidating is absolutely preposterous. I can build confidence by saying "this function creates a string *points finger* "byTrimmingCharacters" *points finger* in a character set *points finger*. The second one? I need to make sure they're comfortable with the documentation and hope they remember that alongside everything else they're learning. The verbosity is a big strength because it feeds the mental associations to them rather than requiring them to keep them around, which benefits me in my ability to scan the code and know what exactly what is being called, as well as the ability to reason very quickly about a method that isn't currently in my working memory.

Also, it's no worse for typing unless the teacher is awful and doesn't teach their students to autocomplete extremely often.

Toady posted:

I'm also biased by accessibility needs. I experience visual snow and ghosting, and big chunks of verbose Cocoa code are irritating to read through, especially after working in concise languages with more whitespace.
That sucks, sorry :/ I'm sort of the opposite; concise languages irritate me greatly and I read them slower as a result.

Doctor w-rw-rw- fucked around with this message at 02:01 on Feb 1, 2016

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

It would be interesting to hear what the pattern is that leads to "trimming" as a method name. What do gerunds convey? Operating on a copy, vs a hypothetical "trim" that would mutate in place?

(Apologies if I missed that in the proposal somewhere.)

lord funk
Feb 16, 2004

Subjunctive posted:

It would be interesting to hear what the pattern is that leads to "trimming" as a method name. What do gerunds convey? Operating on a copy, vs a hypothetical "trim" that would mutate in place?

(Apologies if I missed that in the proposal somewhere.)

You can see the thought process in 'Pruning Steps' from Better Translation of Objective-C APIs Into Swift. And now that I read through pruning to 'with' but removing 'by' and leaving the gerund, I'm just depressed. So scattershot.

Personally, gerunds will always be boolean properties to me, and it is grammatically sideways to make methods with them.

MICHAEL TRIMMING TREE. TREE FALLING LEAVES.

dizzywhip
Dec 23, 2005

lord funk posted:

Personally, gerunds will always be boolean properties to me, and it is grammatically sideways to make methods with them.

MICHAEL TRIMMING TREE. TREE FALLING LEAVES.

I know it's a joke, but that's not really a fair example. You wouldn't see michael.trimming(tree), it would be michael.trim(tree). You might see tree.trimming(leaves) though, because the leaves are part of the tree. The object has to modify the subject in some way for the shorthand to be natural, which is exactly the scenario that Objective-C methods are named xByDoingSomethingToWhatever, which are the APIs that would be translated this way.

jawbroken
Aug 13, 2007

messmate king
I'm having trouble imagining how you bring yourself to use Swift at all if you're so adamantly against these changes. Type inference alone must drive you crazy.

Subjunctive posted:

It would be interesting to hear what the pattern is that leads to "trimming" as a method name. What do gerunds convey? Operating on a copy, vs a hypothetical "trim" that would mutate in place?

I don't know about “trimming” specifically, but that's what sort vs. sorted means, etc.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Doctor w-rw-rw- posted:

The message passing syntax has its roots more in Smalltalk than old limitations, though.

The syntax and basic language semantics are certainly inspired by Smalltalk, but the API naming style is not; Smalltalk message naming style is very terse. For example, Smalltalk collections are indexed with at:, whereas the equivalent NSArray operation is spelled objectAtIndex:.

squidgee posted:

This is an important point. I can't tell you how much of Cocoa I've picked up over the years from autocomplete and verbose method names. If there is a move to more abbreviated method names, I hope that's taken into consideration when translating them. :)

This is an interesting point, but it's pretty much inherently in conflict with trying to use consistent method names across types. For example, NSArray has a slicing operation called subarrayWithRange:, and NSString has one called substringWithRange:. In Swift that would have to be subcollectionWithRange:, at least until someone decides that there's a meaningful level of abstraction below Collection that can still be sliced.

Also, let me try to restate the use pattern here. You want to use autocomplete to suggest what you can do with a value. However, you can't just autocomplete all methods, because that will include all the methods from superclasses, which will clutter up autocomplete with hundreds (if not thousands) of useless options. So this naming convention lets you start with a prefix (that's basically just the name of the type all over again) to tell autocomplete to only tell you about the operations from that type. This works great, provided of course that you're only interested in operations that derive new values of the same type (and so are prefixed with that type name), and also provided that the operation you're interested in does happen to be named with exactly that prefix, as opposed to a slightly different but related prefix (e.g. sortedArrayUsingComparator: or subarrayWithRange:), or a prefix associated with a superclass (e.g. viewWithTag: on an NSText), or no prefix at all (e.g. fileReferenceURL).

I think discoverability is really important, but I am not convinced that this is really an important tool for discovering functionality, or even a good one.

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...
That's how I find my way around the .NET API so it's not too crazy to think that something like it could happen for Swift.

I am endlessly disappointed every time I hit autocomplete in Xcode and get a page full of complete irrelevance. With no characters after foo. at all you should be showing me things that are very close to the type I'm working on, not things like "super".

I don't think the solution is to mangle names here but rather to fix Xcode's suggestions.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Dessert Rose posted:

That's how I find my way around the .NET API so it's not too crazy to think that something like it could happen for Swift.

To be clear, I think autocomplete in general is a great tool for discoverability.

jawbroken
Aug 13, 2007

messmate king

Xcode 7.3 beta 1 release notes posted:

Code completion provides better matches with fewer keystrokes and makes it easier to find what you’re looking for. You can type just the uppercase letters of a method name. Typing "myDelegate.tveh”, where myDelegate is a UITableViewDelegate, gives tableView(_ tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat as the first completion. Completions also match your intent better; for example, typing “myView.color”, where myView is a UIView, gives every property containing the “color” substring, like “tintColor” and “backgroundColor”.

Possibly relevant here, but I haven't tried it yet.

lord funk
Feb 16, 2004

Doctor w-rw-rw- posted:

Having taught programming before, the idea that the greater character count is more intimidating is absolutely preposterous. I can build confidence by saying "this function creates a string *points finger* "byTrimmingCharacters" *points finger* in a character set *points finger*. The second one? I need to make sure they're comfortable with the documentation and hope they remember that alongside everything else they're learning. The verbosity is a big strength because it feeds the mental associations to them rather than requiring them to keep them around, which benefits me in my ability to scan the code and know what exactly what is being called, as well as the ability to reason very quickly about a method that isn't currently in my working memory.

Yes. I find it interesting that I also teach beginning programming and I'm really worried about these changes. When you teach it is a reminder of a time when you didn't understand how code works. stringByTrimmingCharactersInSet is a perfect example of where self-explainatory method names make things much clearer.

Flobbster
Feb 17, 2005

"Cadet Kirk, after the way you cheated on the Kobayashi Maru test I oughta punch you in tha face!"
Joining the bandwagon of people who have taught programming and prefer the extra verbosity of Swift's inherited APIs. I think there is a lot about Swift that would make it a great first teaching language, and the prose-like APIs are part of that. Sure, there are inconsistencies (the first argument name being attached to method name and not the argument list, and the way that affects how the first argument is declared vs all the other arguments), but those can be fixed. Getting rid of unnecessary prefixes is great, but we shouldn't go down the path of making the language look like Perl or Python in its terseness.

Doctor w-rw-rw-
Jun 24, 2008

rjmccall posted:

This is an interesting point, but it's pretty much inherently in conflict with trying to use consistent method names across types. For example, NSArray has a slicing operation called subarrayWithRange:, and NSString has one called substringWithRange:. In Swift that would have to be subcollectionWithRange:, at least until someone decides that there's a meaningful level of abstraction below Collection that can still be sliced.
Why is it necessary to coalesce two operations which, while conceptually similar, typically have different purposes? Unless you're planning on making Strings and character arrays exactly synonymous, the utility of identical method names is at best neutral. But hey, let's introduce API churn because minimizing the amount of similar methods named for their purpose instead of their implementation is ~elegant~.

While there may be an mapping from the old way to the new way, it's still breaking the crap out of APIs at a rather fundamental level. And the translation is, importantly, visually lossy. Objective-C's (and Swift's until now) verbosity has, in addition to the visual advantage, a pedagogical advantage as well – in that what you see is what it does.

This stems from my belief that Objective-C's naming conventions are, fundamentally, good – and that they are helpful to developers. It's a way more visually informative language than others, and that helps with learning, helps with inspection, and enables the creation of very obvious APIs.

<rant>

https://swift.org/blog/swift-api-transformation/ posted:

This is no mere aesthetic concern; non-uniformity and lack of predictability make everything harder, from coding to debugging to maintenance. Fortunately Swift developers created tons of great code in spite of that gap, and along the way, there evolved a sense of what “Swifty” code looks and feels like.
This rings so incredibly false to me. Objective-C's APIs are very helpful for predictability, and makes teaching, coding, debugging, and maintenance easier. I think great Swift code has been created because of this. I hesitate to throw a stronger tantrum (forgive the couple of next paragraphs), but drat, if this change goes through I struggle to imagine the day where I prefer to wrap a Swift core with an Objective-C API rather than write an Objective-C core with Swift, for projects where I want to support both.

It blows my mind that such a far-reaching and fundamental transformation is happening to Swift at this point. I understand that if it's ultimately a positive change, it should happen sooner rather than later. But the case for it is incredibly weak to me, the benefits so minuscule, and the disadvantage very real.

Does the Swift team seriously believe that systematically parsing and extensively munging patterns in not-quite-natural-language is tractable to support all the corner cases for? And that, even if it were, that it could avoid confusion in less-than-perfect codebases? The idea that this will somehow benefit a language, particularly one in which clear and obvious bridging is so vital is insane. The best it can do is a reasonable job, with some amount of either unfixable brokenness forced upon developers in perpetuity, or constant churn stemming from perpetual fixing of brokenness. Swift's translation is currently simple to reason about, and the language as a whole has got a really great thing going on. I'm really happy with where it is at this moment. Why ruin it by boneheadedly detonating the utility of two years of progress in literature and the library of online information about Swift? Seriously, why?

Imitating the Python 2 -> Python 3 transition, except with better translation tools, and even more API disruption, when the language is currently so promising , is incredibly distressing. It doesn't make sense!

</rant>

nah thanks
Jun 18, 2004

Take me out.

rjmccall posted:

This is an interesting point, but it's pretty much inherently in conflict with trying to use consistent method names across types. For example, NSArray has a slicing operation called subarrayWithRange:, and NSString has one called substringWithRange:. In Swift that would have to be subcollectionWithRange:, at least until someone decides that there's a meaningful level of abstraction below Collection that can still be sliced.

Also, let me try to restate the use pattern here. You want to use autocomplete to suggest what you can do with a value. However, you can't just autocomplete all methods, because that will include all the methods from superclasses, which will clutter up autocomplete with hundreds (if not thousands) of useless options. So this naming convention lets you start with a prefix (that's basically just the name of the type all over again) to tell autocomplete to only tell you about the operations from that type. This works great, provided of course that you're only interested in operations that derive new values of the same type (and so are prefixed with that type name), and also provided that the operation you're interested in does happen to be named with exactly that prefix, as opposed to a slightly different but related prefix (e.g. sortedArrayUsingComparator: or subarrayWithRange:), or a prefix associated with a superclass (e.g. viewWithTag: on an NSText), or no prefix at all (e.g. fileReferenceURL).

I think discoverability is really important, but I am not convinced that this is really an important tool for discovering functionality, or even a good one.

This is sort of right. Off the top of my head I can think of two ways that I find the current naming conventions useful via autocomplete:

1) If I'm not familiar with a particular framework, autocomplete helps me to navigate it quicker than referencing the documentation would. I know Apple's usual naming pattern for methods (thisWithThat:, thisDidThat:, thatByDoingSomeAction:, etc.), and I can usually use this knowledge to discover whatever I need to do via autocomplete.

For example, let's say I can't remember some particular method name. This happens to me all the time. I know that what I want exists, but I don't remember exactly what it's called. So how do I find the method name? 90% of the time, I use autocomplete to guess it on the first or second try. For instance, I know that the method for combining two strings is probably something like, "stringByCombiningWithAnotherString:," so I can punch in "stringBy" and stringByAppendingString: pops up. If stringByAppendingString: were renamed something terse like append:, I'd have to resort to the documentation to find it.

That's not a huge deal at the end of the day, but it does mean that it'll take me longer to get my ideas into Xcode.

2) I frequently discover new methods completely by accident. I'm a mostly self-taught programmer (I only took a handful of CS courses in college), and I've only been using Cocoa Touch for about ~3 years. There's a lot that I don't know. So, sometimes I'll start typing in a method that I know exists (let's use stringByAppendingString: again), and autocomplete will suggest some other useful method that I had no idea existed (say, stringByDeletingPathExtension:). This might not seem like a big deal if you've been using Cocoa since the NextStep days, but it's surprisingly helpful to those of us who are relatively new to Apple's frameworks.

Hopefully that clarifies what I meant. And of course, this is all in addition to the concerns I have about readability, which Doctor w-rw-rw- et al are articulating far better than I ever could. I agree with everything he (and basically all of the other anti-change folks) are saying above.

nah thanks fucked around with this message at 21:09 on Feb 1, 2016

lord funk
Feb 16, 2004

Reading through some of the list-serve posts and chucked my 2 cents in. Lots of discussion on parsing problems (verb / noun matches, words falsely registering up as adjectives, etc.). Still looking for the discussion about whether this is a really bad idea or not.

Doctor w-rw-rw-
Jun 24, 2008
Thanks for the quote :blush:

lord funk
Feb 16, 2004

Doctor w-rw-rw- posted:

Thanks for the quote :blush:

Well said!

Kallikrates
Jul 7, 2002
Pro Lurker
My reply is stuck in a moderation queue I think or I don't know how to use mailing lists. Reading responses it seems many people are more concerned with what the new API's will look like and how to convert them all covering all the corner cases, instead of if it was a good idea in the first place.

dizzywhip
Dec 23, 2005

You have to subscribe to the list to avoid the moderation queue: https://lists.swift.org/mailman/listinfo/swift-evolution

Doctor w-rw-rw-
Jun 24, 2008
On the bright side, it should be possible to write class extensions to wrap/reverse the transformations, right? Except when boolean properties overlap API transformations, I guess.

Also, for shits and giggles, and to demonstrate how easy it is to create a situation where you have to be aware of the conversion rules, try and figure out how this ridiculous method would be translated:
Objective-C code:
@interface Bling : NSObject
+ (Bling *)blingByBlingBling:(Bling *)bling;
@end
Use the proposal if you're stumped, and keep in mind that 'bling'' is also a verb.

EDIT: or, and I haven't checked this one yet,
Objective-C code:
@interface Bling : NSObject
+ (Bling *)blingByBlingBlingBling:(Bling *)blingBling;
@end

Doctor w-rw-rw- fucked around with this message at 22:13 on Feb 2, 2016

Kallikrates
Jul 7, 2002
Pro Lurker

dizzywhip posted:

You have to subscribe to the list to avoid the moderation queue: https://lists.swift.org/mailman/listinfo/swift-evolution

I did :( rip my inbox

Adbot
ADBOT LOVES YOU

lord funk
Feb 16, 2004

Kallikrates posted:

I did :( rip my inbox

If you're on Gmail filter them to the Forums category because hot drat.

  • Locked thread