Re: [swift-evolution] [Last second] Precedence of nil-coalescing operator seems too low

2016-09-03 Thread Erica Sadun via swift-evolution
> On Sep 3, 2016, at 10:15 PM, Jacob Bandes-Storch  wrote:
> 
> Perhaps-conversely, what should this code do?
> 
> let nextIndex = foundIndex ?? lastIndex + 1
> 
> Jacob

It's a good counter example. And there's no optional-associative option.

-- E

> 
> On Sat, Sep 3, 2016 at 9:05 PM, Erica Sadun via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> Given: `let x = Optional(3)` then
> `let y = 5 + x ?? 2` will not compile
> but 
> `let y = 5 + (x ?? 2)` will.
> 
> Should NilCoalescingPrecedence be raised? The current operator precedence 
> chain is:
> 
> BitwiseShiftPrecedence > MultiplicationPrecedence > AdditionPrecedence > 
> RangeFormationPrecedence > CastingPrecedence > NilCoalescingPrecedence > 
> ComparisonPrecedence > LogicalConjunctionPrecedence > 
> LogicalDisjunctionPrecedence > TernaryPrecedence > AssignmentPrecedence > 
> FunctionArrowPrecedence > [nothing]
> 
> It seems to me that `NilCoalescingPrecedence` should probably be higher than 
> `MultiplicationPrecedence` and possibly higher `BitwiseShiftPrecedence` as 
> its job is to produce an unwrapped value that can then be operated upon.
> 
> I think CastingPrecedence should be even higher because
> `expression as? T ?? fallback value`
> should be parsed as
> `(expression as? T) ?? (fallback value)`
> 
> I apologize profusely because I know this is beyond last minute,
> 
> -- E
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> 
> 

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


Re: [swift-evolution] [Idea] Use optionals for non-optional parameters

2016-09-03 Thread Justin Jia via swift-evolution


> On Sep 4, 2016, at 1:35 AM, Thorsten Seitz  wrote:
> 
> 
> 
>> Am 03.09.2016 um 18:45 schrieb Justin Jia :
>> 
>> 
>>> On Sep 4, 2016, at 12:19 AM, Thorsten Seitz  wrote:
>>> 
>>> 
>>> 
>>> Am 15.08.2016 um 19:05 schrieb Justin Jia via swift-evolution 
>>> :
>>> 
 I agree that being explicit is nice and I also like to use `guard`.
 
 But according to my observation, usually it is easier to make mistakes if 
 we choose to use `guard`.
 
 Let me give you a fake real world example.
 
 With `guard`, you need to be really careful when you want to add new 
 expression (people usually will add to the end of the function).
 
 ```
 func updateCell(cell: Cell, data: CellData) {
   cell.label.text = data.title
   guard let imageName = data.imageName else { return }
   cell.sublabel.text = cell.humanize(imageName)
   guard let image = UIImage(named: imageName) else { return }
   cell.addBackgroundImage(image)
   // Let's say we changed the design and added a new heading that depends 
 on image name
   cell.heading = String(imageName.characters.first) // This won't be 
 called if image is nil!
 }
 ```
 
 With `if let`, it is really hard to read. This will become more 
 complicated if we add more attributes to cell.
 
 ```
 func updateCell(cell: Cell, data: CellData) {
   cell.label.text = data.title
   if let imageName = data.imageName {
 cell.sublabel.text = cell.humanize(imageName)
 if let image = UIImage(name: imageName) {
   cell.addBackgroundImage(image)
 }
 cell.heading = String(imageName.characters.first)
   }
 }
 ```
 
 With the proposed syntax:
 
 ```
 func updateCell(cell: Cell, data: CellData) {
   cell.label.text = data.title
   let imageName = data.imageName // imageName is optional
   cell.sublabel.text = cell.humanize(imageName?)
   let image = UIImage(named: imageName?) // image is optional
   cell.addBackgroundImage(image?)
   cell.heading = String(imageName.characters.first?)
 }
 ```
 
 This is really easy to read. And everything works correctly.
>>> 
>>> It is even easier if you define the methods on Cell to take optional 
>>> arguments. 
>>> Then you can write the code like in your last example and don't even need 
>>> the proposed syntax:
>>> 
>>> class Cell {
>>> let label = UILabel()
>>> let sublabel = UILabel()
>>> var heading: String?
>>> func humanize(_ string: String?) -> String {...}// optional argument
>>> func addBackgroundImage(_ image: UIImage?)// optional argument
>>> }
>>> 
>>> extension UIImage {
>>> init?(named imageName: String?) {...}
>>> }
>>> 
>>> extension String {
>>> init?(named imageName: Character?) {...}
>>> }
>>> 
>>> func updateCell(cell: Cell, data: CellData) {
>>>   cell.label.text = data.title
>>>   let imageName = data.imageName
>>>   cell.sublabel.text = cell.humanize(imageName)
>>>   let image = UIImage(named: imageName)
>>>   cell.addBackgroundImage(image)
>>>   cell.heading = String(imageName?.characters?.first)
>>> }
>>> 
>>> -Thorsten 
>> 
>> 
>> Quoting another email:
>> 
>>> Actually there is an easy fix: make all functions accept optionals. I think 
>>> this is a really bad idea because sometimes functions are designed to 
>>> accept non-optionals.
>>> 
>>> e.g.
>>> 
>>> ```
>>> func addSubview(_ view: UIView) { }
>>> ```
>>> 
>>> It doesn’t make sense if we want to add nil as the subview, so we choose to 
>>> write code like this:
>>> 
>>> ```
>>> if let view = view {
>>> addSubview(view)
>>> }
>>> ```
>> 
> 
> I agree. The proposal effectively does just that, though: turn every function 
> into a function accepting optionals (returning nil if any argument is nil). I 
> would prefer to do this explicitly in cases where it makes sense and use map 
> or let-bindings elsewhere.
> 
> -Thorsten 

I was thinking about a precondition syntax. But I think it's too complicated. I 
agree. Maybe do this explicitly is better. 

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


Re: [swift-evolution] [Review] SE-0140: Bridge Optional As Its Payload Or NSNull

2016-09-03 Thread Jacob Bandes-Storch via swift-evolution
>
> https://github.com/apple/swift-evolution/blob/master/
> proposals/0140-bridge-optional-to-nsnull.md
>
>
>- What is your evaluation of the proposal?
>
> I tend to agree with other commenters that NSNull does not seem like an
obviously-correct (or -unsurprising) solution to this problem. Rather than
getting "unexpectedly found nil" errors like in Swift, this would start
causing more obtuse errors about missing methods on NSNull.

Users could simply be forced to write `?? NSNull()` if they really want to
use NSNull.

I do think that a warning/error for Optional-to-Any conversion should be
added; something like:

- (void)test:(id _Nonnull)arg;
let x: Int? = 3
test(x)  // passing optional type 'Int?' to 'Any' parameter uses an
opaque wrapper; use 'as Any' to silence this warning

Although, I'm not sure that would be a complete solution, because you could
still get around it with generic algorithms. This example is contrived, but:

extension Array {
func asAnys() -> [Any] {
return map { $0 as Any }// no warning here; $0's type is
Element, not known whether optional or non-optional
}
}

It might be nice for this warning to occur *only* when passing values to
Obj-C methods. Swift code written using Any would handle them correctly.
However, I'm not sure that's possible, given that the Obj-C importer
recently started using Any instead of AnyObject on purpose to make Obj-C
code more like Swift code in that way.


>
>- Is the problem being addressed significant enough to warrant a
>change to Swift?
>
> Definitely; the current behavior is surprising and dangerous.



>
>- Does this proposal fit well with the feel and direction of Swift?
>
> Not really; it seems like a Cocoa-ism leaking into the purity/safety of
Swift, more so than most bridging behavior, although perhaps I'm only
saying this because NSNull is much less commonly used than the most other
bridged types.



>
>- If you have used other languages or libraries with a similar
>feature, how do you feel that this proposal compares to those?
>
> N/A



>
>- How much effort did you put into your review? A glance, a quick
>reading, or an in-depth study?
>
> A quick reading of the proposal, plus some experimentation in a sample
project and discussion with others in Slack about an occurrence of the
motivating problem.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Last second] Precedence of nil-coalescing operator seems too low

2016-09-03 Thread Jacob Bandes-Storch via swift-evolution
Perhaps-conversely, what should this code do?

let nextIndex = foundIndex ?? lastIndex + 1

Jacob

On Sat, Sep 3, 2016 at 9:05 PM, Erica Sadun via swift-evolution <
swift-evolution@swift.org> wrote:

> Given: `let x = Optional(3)` then
>
> `let y = 5 + x ?? 2` will not compile
>
> but
>
> `let y = 5 + (x ?? 2)` will.
>
>
> Should NilCoalescingPrecedence be raised? The current operator precedence
> chain is:
>
> BitwiseShiftPrecedence > MultiplicationPrecedence > AdditionPrecedence >
> RangeFormationPrecedence > CastingPrecedence > NilCoalescingPrecedence >
> ComparisonPrecedence > LogicalConjunctionPrecedence >
> LogicalDisjunctionPrecedence > TernaryPrecedence > AssignmentPrecedence >
> FunctionArrowPrecedence > [nothing]
>
>
> It seems to me that `NilCoalescingPrecedence` should probably be higher
> than `MultiplicationPrecedence` and possibly higher `
> BitwiseShiftPrecedence` as its job is to produce an unwrapped value that
> can then be operated upon.
>
> I think CastingPrecedence should be even higher because
>
> `expression as? T ?? fallback value`
>
> should be parsed as
>
> `(expression as? T) ?? (fallback value)`
>
>
> I apologize profusely because I know this is beyond last minute,
>
> -- E
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] [Last second] Precedence of nil-coalescing operator seems too low

2016-09-03 Thread Erica Sadun via swift-evolution
Given: `let x = Optional(3)` then
`let y = 5 + x ?? 2` will not compile
but 
`let y = 5 + (x ?? 2)` will.

Should NilCoalescingPrecedence be raised? The current operator precedence chain 
is:

BitwiseShiftPrecedence > MultiplicationPrecedence > AdditionPrecedence > 
RangeFormationPrecedence > CastingPrecedence > NilCoalescingPrecedence > 
ComparisonPrecedence > LogicalConjunctionPrecedence > 
LogicalDisjunctionPrecedence > TernaryPrecedence > AssignmentPrecedence > 
FunctionArrowPrecedence > [nothing]

It seems to me that `NilCoalescingPrecedence` should probably be higher than 
`MultiplicationPrecedence` and possibly higher `BitwiseShiftPrecedence` as its 
job is to produce an unwrapped value that can then be operated upon.

I think CastingPrecedence should be even higher because
`expression as? T ?? fallback value`
should be parsed as
`(expression as? T) ?? (fallback value)`

I apologize profusely because I know this is beyond last minute,

-- E

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


Re: [swift-evolution] SE-0138 UnsafeBytes

2016-09-03 Thread Andrew Trick via swift-evolution

> On Sep 3, 2016, at 3:36 PM, Drew Crawford  wrote:
> 
> 
> On September 2, 2016 at 2:36:43 AM, Andrew Trick (atr...@apple.com 
> ) wrote:
> 
>> After thinking about this for a moment, I like the approach of extending 
>> UnsafeBytes with release-mode bounds checked versions of subscript, load, 
>> and storeBytes.
> 
> I agree with this, I think it's mostly a question of naming and defaults.  My 
> concern here is letting a swift developer accidentally write heartbleed, 
> which we can't actually prevent, but we can make it harder.
> 
> IMO 
> 
> 1.  There should be clear consistency in the checked-ness of the API surface. 
>  Agree that checked iterator makes no sense, but I think the most important 
> thing is to avoid creating a job interview trivia game where `set` is checked 
> but `store` is unchecked, spot the bug in this function.
> 
> 2.  For consistency with UnsafeBufferPointer it may make the most sense to 
> just ship unchecked or ship an opt-in checked wrapper.  I believe however 
> that the existing precedent is all wrong on this point, and I'd like to see 
> us revisit this question across both interfaces in Swift 4, but I don't want 
> to lay out a whole case here that should be its own thread.
> 
I generally agree with what you said. I think the vague plan is later in Swift 
4 to ship a bounds-checked variant of both UnsafeBufferPointer and UnsafeBytes 
(or  UnsafeRawBufferPointer if you prefer).

I don’t want to eliminate the debug-mode checks though. I did try to make it 
clear in the comments that bounds-checking only applied to debug mode, so 
developers should not accidentally become too reliant on them.

So, the only question is whether the UnsafeBytes.copyBytes() API should have 
debug or release-mode checks. My decision to keep the stronger checks here was 
probabilistic—it seems unlikely to be a performance issue but likely to catch 
most buffer overruns. But I agree that it is inconsistent, especially if we 
plan to introduce a release bounds-checked variant later. We don’t want 
developers to begin relying on that check. I’m leaning toward dropping it down 
to a debug-mode check.

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


Re: [swift-evolution] SE-0138 UnsafeBytes

2016-09-03 Thread Drew Crawford via swift-evolution

On September 2, 2016 at 2:36:43 AM, Andrew Trick (atr...@apple.com) wrote:

After thinking about this for a moment, I like the approach of extending 
UnsafeBytes with release-mode bounds checked versions of subscript, load, and 
storeBytes.
I agree with this, I think it's mostly a question of naming and defaults.  My 
concern here is letting a swift developer accidentally write heartbleed, which 
we can't actually prevent, but we can make it harder.

IMO 

1.  There should be clear consistency in the checked-ness of the API surface.  
Agree that checked iterator makes no sense, but I think the most important 
thing is to avoid creating a job interview trivia game where `set` is checked 
but `store` is unchecked, spot the bug in this function.

2.  For consistency with UnsafeBufferPointer it may make the most sense to just 
ship unchecked or ship an opt-in checked wrapper.  I believe however that the 
existing precedent is all wrong on this point, and I'd like to see us revisit 
this question across both interfaces in Swift 4, but I don't want to lay out a 
whole case here that should be its own thread.

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


Re: [swift-evolution] [swift-evolution-announce] SE-0138 UnsafeBytes

2016-09-03 Thread Drew Crawford via swift-evolution

On September 2, 2016 at 3:34:56 PM, Tony Parker via swift-evolution 
(swift-evolution@swift.org) wrote:
I think instead handleMessages should take a Data argument.
The core issue here is that the problem solved here is not a "foundation 
problem", it is a "stdlib problem".  They are superficially similar in that 
both of them involve an array of bytes but the comparison ends there.

The motivation for Data/NSData is we have a logical collection of bytes.  That 
collection may be contiguous or discontiguous (speaking only of API; I'm 
unfamiliar with the implementation choice).    It may be created from a file or 
even a URL, from a base64 representation, it may share the underlying memory 
with other NSData instance or not.

What we are considering here is a *physical* collection of bytes, e.g. a 
pointer and a length.  By definition, they do not share memory with each other 
(unless they overlap, which is you can find out with public API).  By 
definition, they are contiguous.  

Data is the abstraction to choose when you don't care how the memory is laid 
out.  UnsafeBytes is the abstraction to choose when the memory layout is the 
critical property.  e.g., you are bitshifting between the IEEE754 fields to 
implement fastinvsqrt, or you are converting between sockaddr and sockaddr_in 
(same type but different sizes).  

These are not I/O problems or array problems.  They are C pointer problems, 
where we want to dispense with the traditional Swift abstractions and view the 
world as C arrays again like it's 1970.

Like all pointer problems in the language, they aren't foundation problems and 
we should not solve them there, whether we are under time pressure or with all 
the time in the world.  They should be solved where we solve the other pointer 
problems, which is in the stdlib.

I think instead handleMessages should take a Data argument. The input driver 
code should be able to use API on Data (or elsewhere, API that returns Data) to 
populate it with the contents of the file.
The core API in my networking project is fairly similar to this example, and in 
that case, NSData was not the right choice, because it does not support

Uninitialized arrays
Explicitly managing zero-cost "views" of the underlying memory by creating 
instances that refer to the same location and sliding the start and end markers
Casting unsafely between arrays of different size
Working with memory regions where the size is not known at compile time but is 
discovered during a read such as pascal strings or msgpack
These are totally ridiculous additions to the Data API surface.  Somebody who 
wants to load a URL should never see this garbage in their autocomplete.  But 
they are things C programmers frequently do.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0140: Bridge Optional As Its Payload Or NSNull

2016-09-03 Thread Charles Srstka via swift-evolution
> On Sep 3, 2016, at 3:01 AM, Pyry Jahkola  wrote:
> 
>> On 03 Sep 2016, at 03:17, Charles Srstka via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> With the existing behavior, such mistakes are immediately obvious as 
>> Objective-C receives an opaque object that it cannot use (and probably soon 
>> crashes), so they are unlikely to make it past QA testing.
> 
> How is this different with NSNull though? If the callee expects an array of 
> NSNumbers for example and uses them (for anything more specific than 
> NSObject), the first NSNull instance will throw an NSInvalidArgumentException 
> basically crashing the program as well:

The difference is that with the existing behavior, any call to *any* object in 
the array will throw an exception, whether the original was an NSNull or not. 
This will alert you right away to the fact that you accidentally sent an 
optional array to an Objective-C API. With this proposal, if the objects in the 
array are usually non-nil, you might never realize that you accidentally made 
the array optional, and you won’t find out until some weird edge case results 
in a nil getting stuck in there and then *surprise!* your users are reporting 
random crashes in your app that are really hard to track down!

Optional arrays are pretty easy to make by accident. I know that I’ve done it 
far more than I’ve used anything that required an NSNull. The thing is, if 
you’ve made one, you usually find out about it pretty quickly because you get 
compiler errors when passing it to other Swift APIs, and, in the worst case, 
instant and obvious runtime errors when passing it to Objective-C APIs. With 
the proposal, accidental optional arrays will suddenly become silent and deadly 
in Objective-C.

Charles

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


Re: [swift-evolution] The great renaming and the state of new Unified Logging in Swift

2016-09-03 Thread Ben Rimmington via swift-evolution

> On 3 Sep 2016, at 19:13, Brandon Knope  wrote:
> 
> Thank you! I was looking for this last night and failed. 
> 
> Why do you think {public} isn't included?

I don't know, but trying to reimplement __builtin_os_log_format in the overlay 
seems wrong. It would be better to have a variant of __builtin_os_log_format 
which takes a va_list.

-- Ben

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


Re: [swift-evolution] The great renaming and the state of new Unified Logging in Swift

2016-09-03 Thread Brandon Knope via swift-evolution
Thank you! I was looking for this last night and failed. 

Why do you think {public} isn't included?

Sent from my iPad

> On Sep 3, 2016, at 2:06 PM, Ben Rimmington  wrote:
> 
> 
>> On 3 Sep 2016, at 04:24, Brandon Knope wrote:
>> 
>> I am unsure where to post this…but iOS 10 is introducing a new API for 
>> activity tracing and logging.
>> 
>> The API has been “Swift-ified” a little, but it still is a little awkward to 
>> use:
>> 
>> os_log("Sender: %{public}@", log: ViewController.ui_log, type: .debug, 
>> sender)
>> 
>> (This is taken from: 
>> https://developer.apple.com/library/prerelease/content/samplecode/Logging/Introduction/Intro.html#//apple_ref/doc/uid/TP40017510)
>> 
>> Note: the {public} modifier above does not work in swift but does in 
>> Objective-C. I have filed a radar for this.
> 
> Activity Tracing (2014) and Unified Logging (2016) APIs are complex 
> preprocessor macros, which are not imported into Swift.
> 
>   
> 
>   
> 
> The os_log_with_type macro in  uses __builtin_os_log_format to 
> encode its arguments into a byte array. The overlay for Swift instead uses 
> its _os_log_encode C++ function, which only recognizes the {private} modifier.
> 
>   
> 
> 
>   
> 
>> A few things:
>> • This looks like how the Dispatch APIs use to look: very C-like which was 
>> made to be much better in The Great Renaming
>> • Cannot use Swift’s string interpolation, resulting in the arguments being 
>> passed in at the end
>> 
>> For reference, this is what it looks like in Objective-C, showing that SOME 
>> renaming has occurred: 
>> os_log_debug(ui_log, "Sender: %{public}@", sender);
>> 
>> This might look more Swift-like:
>> uiLog.log("Sender: %{public}\(sender)”, type: .debug)
>> * Makes “log” a method on an OSLog object 
>> • Uses string interpolation
> 
> The format string of os_log APIs is required to be constant. The overlay uses 
> a StaticString, which isn't ExpressibleByStringInterpolation. SE-0137 also 
> deprecated the protocol, so that it can be redesigned.
> 
>   
> 
> 
> An instance method of OSLog might be better, except when using the `default` 
> object.
> 
>   OSLog.default.log("message")
> 
> Similarly, the Swift.print(_:separator:terminator:to:) function might be 
> better as a TextOutputStream method.
> 
> -- Ben
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] The great renaming and the state of new Unified Logging in Swift

2016-09-03 Thread Ben Rimmington via swift-evolution

> On 3 Sep 2016, at 04:24, Brandon Knope wrote:
> 
> I am unsure where to post this…but iOS 10 is introducing a new API for 
> activity tracing and logging.
> 
> The API has been “Swift-ified” a little, but it still is a little awkward to 
> use:
> 
> os_log("Sender: %{public}@", log: ViewController.ui_log, type: .debug, sender)
> 
> (This is taken from: 
> https://developer.apple.com/library/prerelease/content/samplecode/Logging/Introduction/Intro.html#//apple_ref/doc/uid/TP40017510
>  
> )
> 
> Note: the {public} modifier above does not work in swift but does in 
> Objective-C. I have filed a radar for this.

Activity Tracing (2014) and Unified Logging (2016) APIs are complex 
preprocessor macros, which are not imported into Swift.





The os_log_with_type macro in  uses __builtin_os_log_format to encode 
its arguments into a byte array. The overlay for Swift instead uses its 
_os_log_encode C++ function, which only recognizes the {private} modifier.






> A few things:
> • This looks like how the Dispatch APIs use to look: very C-like which was 
> made to be much better in The Great Renaming
> • Cannot use Swift’s string interpolation, resulting in the arguments being 
> passed in at the end
> 
> For reference, this is what it looks like in Objective-C, showing that SOME 
> renaming has occurred: 
> os_log_debug(ui_log, "Sender: %{public}@", sender);
> 
> This might look more Swift-like:
> uiLog.log("Sender: %{public}\(sender)”, type: .debug)
> * Makes “log” a method on an OSLog object 
> • Uses string interpolation

The format string of os_log APIs is required to be constant. The overlay uses a 
StaticString, which isn't ExpressibleByStringInterpolation. SE-0137 also 
deprecated the protocol, so that it can be redesigned.




An instance method of OSLog might be better, except when using the `default` 
object.

OSLog.default.log("message")

Similarly, the Swift.print(_:separator:terminator:to:) function might be better 
as a TextOutputStream method.

-- Ben

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


Re: [swift-evolution] [Idea] Use optionals for non-optional parameters

2016-09-03 Thread Thorsten Seitz via swift-evolution


> Am 03.09.2016 um 18:45 schrieb Justin Jia :
> 
> 
>> On Sep 4, 2016, at 12:19 AM, Thorsten Seitz  wrote:
>> 
>> 
>> 
>> Am 15.08.2016 um 19:05 schrieb Justin Jia via swift-evolution 
>> :
>> 
>>> I agree that being explicit is nice and I also like to use `guard`.
>>> 
>>> But according to my observation, usually it is easier to make mistakes if 
>>> we choose to use `guard`.
>>> 
>>> Let me give you a fake real world example.
>>> 
>>> With `guard`, you need to be really careful when you want to add new 
>>> expression (people usually will add to the end of the function).
>>> 
>>> ```
>>> func updateCell(cell: Cell, data: CellData) {
>>>   cell.label.text = data.title
>>>   guard let imageName = data.imageName else { return }
>>>   cell.sublabel.text = cell.humanize(imageName)
>>>   guard let image = UIImage(named: imageName) else { return }
>>>   cell.addBackgroundImage(image)
>>>   // Let's say we changed the design and added a new heading that depends 
>>> on image name
>>>   cell.heading = String(imageName.characters.first) // This won't be called 
>>> if image is nil!
>>> }
>>> ```
>>> 
>>> With `if let`, it is really hard to read. This will become more complicated 
>>> if we add more attributes to cell.
>>> 
>>> ```
>>> func updateCell(cell: Cell, data: CellData) {
>>>   cell.label.text = data.title
>>>   if let imageName = data.imageName {
>>> cell.sublabel.text = cell.humanize(imageName)
>>> if let image = UIImage(name: imageName) {
>>>   cell.addBackgroundImage(image)
>>> }
>>> cell.heading = String(imageName.characters.first)
>>>   }
>>> }
>>> ```
>>> 
>>> With the proposed syntax:
>>> 
>>> ```
>>> func updateCell(cell: Cell, data: CellData) {
>>>   cell.label.text = data.title
>>>   let imageName = data.imageName // imageName is optional
>>>   cell.sublabel.text = cell.humanize(imageName?)
>>>   let image = UIImage(named: imageName?) // image is optional
>>>   cell.addBackgroundImage(image?)
>>>   cell.heading = String(imageName.characters.first?)
>>> }
>>> ```
>>> 
>>> This is really easy to read. And everything works correctly.
>> 
>> It is even easier if you define the methods on Cell to take optional 
>> arguments. 
>> Then you can write the code like in your last example and don't even need 
>> the proposed syntax:
>> 
>> class Cell {
>> let label = UILabel()
>> let sublabel = UILabel()
>> var heading: String?
>> func humanize(_ string: String?) -> String {...}// optional argument
>> func addBackgroundImage(_ image: UIImage?)// optional argument
>> }
>> 
>> extension UIImage {
>> init?(named imageName: String?) {...}
>> }
>> 
>> extension String {
>> init?(named imageName: Character?) {...}
>> }
>> 
>> func updateCell(cell: Cell, data: CellData) {
>>   cell.label.text = data.title
>>   let imageName = data.imageName
>>   cell.sublabel.text = cell.humanize(imageName)
>>   let image = UIImage(named: imageName)
>>   cell.addBackgroundImage(image)
>>   cell.heading = String(imageName?.characters?.first)
>> }
>> 
>> -Thorsten 
> 
> 
> Quoting another email:
> 
>> Actually there is an easy fix: make all functions accept optionals. I think 
>> this is a really bad idea because sometimes functions are designed to accept 
>> non-optionals.
>> 
>> e.g.
>> 
>> ```
>> func addSubview(_ view: UIView) { }
>> ```
>> 
>> It doesn’t make sense if we want to add nil as the subview, so we choose to 
>> write code like this:
>> 
>> ```
>> if let view = view {
>> addSubview(view)
>> }
>> ```
> 

I agree. The proposal effectively does just that, though: turn every function 
into a function accepting optionals (returning nil if any argument is nil). I 
would prefer to do this explicitly in cases where it makes sense and use map or 
let-bindings elsewhere.

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


Re: [swift-evolution] [Idea] Use optionals for non-optional parameters

2016-09-03 Thread Justin Jia via swift-evolution

> On Sep 4, 2016, at 12:19 AM, Thorsten Seitz  wrote:
> 
> 
> 
> Am 15.08.2016 um 19:05 schrieb Justin Jia via swift-evolution 
> mailto:swift-evolution@swift.org>>:
> 
>> I agree that being explicit is nice and I also like to use `guard`.
>> 
>> But according to my observation, usually it is easier to make mistakes if we 
>> choose to use `guard`.
>> 
>> Let me give you a fake real world example.
>> 
>> With `guard`, you need to be really careful when you want to add new 
>> expression (people usually will add to the end of the function).
>> 
>> ```
>> func updateCell(cell: Cell, data: CellData) {
>>   cell.label.text = data.title
>>   guard let imageName = data.imageName else { return }
>>   cell.sublabel.text = cell.humanize(imageName)
>>   guard let image = UIImage(named: imageName) else { return }
>>   cell.addBackgroundImage(image)
>>   // Let's say we changed the design and added a new heading that depends on 
>> image name
>>   cell.heading = String(imageName.characters.first) // This won't be called 
>> if image is nil!
>> }
>> ```
>> 
>> With `if let`, it is really hard to read. This will become more complicated 
>> if we add more attributes to cell.
>> 
>> ```
>> func updateCell(cell: Cell, data: CellData) {
>>   cell.label.text = data.title
>>   if let imageName = data.imageName {
>> cell.sublabel.text = cell.humanize(imageName)
>> if let image = UIImage(name: imageName) {
>>   cell.addBackgroundImage(image)
>> }
>> cell.heading = String(imageName.characters.first)
>>   }
>> }
>> ```
>> 
>> With the proposed syntax:
>> 
>> ```
>> func updateCell(cell: Cell, data: CellData) {
>>   cell.label.text = data.title
>>   let imageName = data.imageName // imageName is optional
>>   cell.sublabel.text = cell.humanize(imageName?)
>>   let image = UIImage(named: imageName?) // image is optional
>>   cell.addBackgroundImage(image?)
>>   cell.heading = String(imageName.characters.first?)
>> }
>> ```
>> 
>> This is really easy to read. And everything works correctly.
> 
> It is even easier if you define the methods on Cell to take optional 
> arguments. 
> Then you can write the code like in your last example and don't even need the 
> proposed syntax:
> 
> class Cell {
> let label = UILabel()
> let sublabel = UILabel()
> var heading: String?
> func humanize(_ string: String?) -> String {...}// optional argument
> func addBackgroundImage(_ image: UIImage?)// optional argument
> }
> 
> extension UIImage {
> init?(named imageName: String?) {...}
> }
> 
> extension String {
> init?(named imageName: Character?) {...}
> }
> 
> func updateCell(cell: Cell, data: CellData) {
>   cell.label.text = data.title
>   let imageName = data.imageName
>   cell.sublabel.text = cell.humanize(imageName)
>   let image = UIImage(named: imageName)
>   cell.addBackgroundImage(image)
>   cell.heading = String(imageName?.characters?.first)
> }
> 
> -Thorsten 


Quoting another email:

> Actually there is an easy fix: make all functions accept optionals. I think 
> this is a really bad idea because sometimes functions are designed to accept 
> non-optionals.
> 
> e.g.
> 
> ```
> func addSubview(_ view: UIView) { }
> ```
> 
> It doesn’t make sense if we want to add nil as the subview, so we choose to 
> write code like this:
> 
> ```
> if let view = view {
> addSubview(view)
> }
> ```

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


Re: [swift-evolution] The great renaming and the state of new Unified Logging in Swift

2016-09-03 Thread Goffredo Marocchi via swift-evolution
I am still not clear how os_log is supposed to be used with Swift if you are 
not one of the elected ones that can ride his white horse straight into iOS 10+ 
only land of apps ;). In Objective-C I can use a macro, as wrapper functions 
are banned, but in Swift? Are availability checks every time I log the answer?

Sent from my iPhone

> On 3 Sep 2016, at 17:28, Jean-Daniel Dupas via swift-evolution 
>  wrote:
> 
> 
>>> Le 3 sept. 2016 à 06:43, Georgios Moschovitis via swift-evolution 
>>>  a écrit :
>>> 
>>> Can it be corrected in Swift 4 (breaking changes etc…)?
>> 
>> Good question.
>> Maybe the core team should accept additional source-breaking changes in 3.x 
>> releases?
> 
> 
> I think the framework API mapping itself is not part of the language and is 
> handle by Apple directly (at least for Apple specifics frameworks). I don’t 
> know if such changes are subject to the same policy.
> 
> 
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] The great renaming and the state of new Unified Logging in Swift

2016-09-03 Thread Jean-Daniel Dupas via swift-evolution

> Le 3 sept. 2016 à 06:43, Georgios Moschovitis via swift-evolution 
>  a écrit :
> 
>> Can it be corrected in Swift 4 (breaking changes etc…)?
> 
> Good question.
> Maybe the core team should accept additional source-breaking changes in 3.x 
> releases?


I think the framework API mapping itself is not part of the language and is 
handle by Apple directly (at least for Apple specifics frameworks). I don’t 
know if such changes are subject to the same policy.




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


Re: [swift-evolution] [Pitch]: Require parenthesis for ternary operator '?:' or change its priority

2016-09-03 Thread Thorsten Seitz via swift-evolution


> Am 03.09.2016 um 13:55 schrieb David Sweeris :
> 
> I don't he's proposing to change the precedence of "?:" per se, just 
> requiring — as part of its syntax — it to be enclosed in parens when it's not 
> by itself:

Ah, ok, I didn't get that. That makes more sense, then :-)

-Thorsten 


> 
> x = condition ? y : z //ok, since it's by itself
> x = (test || condition) ? y : z //ok, since it's still technically by itself
> x = test || (condition ? y : z) //ok, has parens
> x = test || condition ? y : z //syntax error, no parens
> 
> I don't actually know what the correct precedence for ?: is because I never 
> use that 4th "form", for the very reason this change is being proposed: it's 
> too easy for me to get mixed up otherwise.
> 
> Where was I? Oh, right, as I understand it, this doesn't so much change ?:'s 
> precedence as it does remove it from the precedence "system".
> 
> - Dave Sweeris
> 
> Sent from my iPhone, without sleep.
> 
>> On Sep 3, 2016, at 06:21, Thorsten Seitz via swift-evolution 
>>  wrote:
>> 
>> The problem you describe is not the priority of the ternary operator but 
>> that developers just assume a priority without checking (or learning) 
>> whether their assumption is correct. Changing the priority won't solve that 
>> problem, it would only shift the problem over to those developers assuming 
>> the other priority. Worse, it would create this problem for those developers 
>> knowing the correct priority, because they now have to relearn the new 
>> priority with the added difficulty of the priority being different from C.
>> 
>> I'm not sure whether the problem really is one (other operators have 
>> priorities too, which have to be learned), but assuming for the moment that 
>> it is, a solution would be to replace the ternary operator with an 
>> if-expression: if condition then expr1 else expr2
>> This would enclose the condition between two keywords and thereby be free of 
>> misunderstandings.
>> Replacing the ternary operator is on the commonly asked changes list, 
>> though, and therefore requires new arguments/insights why a replacement 
>> would make sense. I think the possibly confusing priority has been discussed 
>> already in the past and therefore wouldn't count as new insight, though I'm 
>> not quite sure.
>> 
>> -Thorsten 
>> 
>>> Am 03.09.2016 um 11:34 schrieb Vladimir.S via swift-evolution 
>>> :
>>> 
>>> (Seems my first email was not resent by mailing list due to its temporary 
>>> problems. So second attempt)
>>> 
>>> I'm not sure if it is a correct time to discuss this, if not - I'll hold 
>>> this for later time.
>>> 
>>> I was reading the article of author of some C/C++ static code analyzer tool 
>>> where he was analyzing and discussing about code of some open source 
>>> program. And there was a paragraph about bugs people make when using 
>>> ternary operator. There a lot of bugs in C/C++ sources of well-known open 
>>> source programs(like Chromium, ReactOS, MongoDB, Unreal Engine 4, Wine, 
>>> FreeBSD Kernel and many others) made when developer assumes that priority 
>>> of '?:' operator is higher than other operators like '+', '*', '|', '&' and 
>>> other.
>>> 
>>> Examples:
>>> 
>>> int edge_height = titlebar_bottom->height() -
>>>ShouldShowClientEdge() ? kClientEdgeThickness : 0;
>>> 
>>> ULONG treg = 0x54 + (dev < 3) ? (dev << 1) : 7;
>>> 
>>> if (IP_PACKET_SIZE < parsedPacket.info.H263.dataLength +
>>>   parsedPacket.info.H263.insert2byteStartCode ? 2:0) {...}
>>> 
>>> stringstream ss;
>>> ss << (sizeof(char *) == 8) ? " 64bit" : " 32bit";
>>> 
>>> return UniformVectorExpressions.GetAllocatedSize()
>>>  + UniformScalarExpressions.GetAllocatedSize()
>>>  + Uniform2DTextureExpressions.GetAllocatedSize()
>>>  + UniformCubeTextureExpressions.GetAllocatedSize()
>>>  + ParameterCollections.GetAllocatedSize()
>>>  + UniformBufferStruct
>>>  ?
>>>  (sizeof(FUniformBufferStruct) +
>>>   UniformBufferStruct->GetMembers().GetAllocatedSize())
>>>  :
>>>  0;
>>> 
>>> .. and so on..
>>> 
>>> Yes, in Swift we have no problem with mixing lets say Ints and Boolean 
>>> values. But, it seems that it is highly possible to catch the same kind of 
>>> problem with ternary operator in Swift for boolean values:
>>> 
>>> func isOne()->Bool { print(1); return false }
>>> func isTwo()->Bool { print(2); return false }
>>> 
>>> let a = true
>>> let b = true
>>> 
>>> let result = a || (b) ? isOne() : isTwo() // prints 1
>>> 
>>> print(result) // false
>>> 
>>> As you understand, to work correctly we need parentheses:
>>> let result = a || ((b) ? isOne() : isTwo()) // 
>>> print(result) // true
>>> 
>>> ..or set priority of '?:' operator higher than other operators (but this 
>>> probably could *silently* break old code?)
>>> 
>>> I was trying to play with custom operators and ternary operator :
>>> 
>>> func <<(lhs: inout String, rhs: String) { lhs += rhs }
>>> func <<(lhs: inout String, rhs: Bool) { lhs 

Re: [swift-evolution] [Idea] Use optionals for non-optional parameters

2016-09-03 Thread Thorsten Seitz via swift-evolution


> Am 15.08.2016 um 19:05 schrieb Justin Jia via swift-evolution 
> :
> 
> I agree that being explicit is nice and I also like to use `guard`.
> 
> But according to my observation, usually it is easier to make mistakes if we 
> choose to use `guard`.
> 
> Let me give you a fake real world example.
> 
> With `guard`, you need to be really careful when you want to add new 
> expression (people usually will add to the end of the function).
> 
> ```
> func updateCell(cell: Cell, data: CellData) {
>   cell.label.text = data.title
>   guard let imageName = data.imageName else { return }
>   cell.sublabel.text = cell.humanize(imageName)
>   guard let image = UIImage(named: imageName) else { return }
>   cell.addBackgroundImage(image)
>   // Let's say we changed the design and added a new heading that depends on 
> image name
>   cell.heading = String(imageName.characters.first) // This won't be called 
> if image is nil!
> }
> ```
> 
> With `if let`, it is really hard to read. This will become more complicated 
> if we add more attributes to cell.
> 
> ```
> func updateCell(cell: Cell, data: CellData) {
>   cell.label.text = data.title
>   if let imageName = data.imageName {
> cell.sublabel.text = cell.humanize(imageName)
> if let image = UIImage(name: imageName) {
>   cell.addBackgroundImage(image)
> }
> cell.heading = String(imageName.characters.first)
>   }
> }
> ```
> 
> With the proposed syntax:
> 
> ```
> func updateCell(cell: Cell, data: CellData) {
>   cell.label.text = data.title
>   let imageName = data.imageName // imageName is optional
>   cell.sublabel.text = cell.humanize(imageName?)
>   let image = UIImage(named: imageName?) // image is optional
>   cell.addBackgroundImage(image?)
>   cell.heading = String(imageName.characters.first?)
> }
> ```
> 
> This is really easy to read. And everything works correctly.

It is even easier if you define the methods on Cell to take optional arguments. 
Then you can write the code like in your last example and don't even need the 
proposed syntax:

class Cell {
let label = UILabel()
let sublabel = UILabel()
var heading: String?
func humanize(_ string: String?) -> String {...}// optional argument
func addBackgroundImage(_ image: UIImage?)// optional argument
}

extension UIImage {
init?(named imageName: String?) {...}
}

extension String {
init?(named imageName: Character?) {...}
}

func updateCell(cell: Cell, data: CellData) {
  cell.label.text = data.title
  let imageName = data.imageName
  cell.sublabel.text = cell.humanize(imageName)
  let image = UIImage(named: imageName)
  cell.addBackgroundImage(image)
  cell.heading = String(imageName?.characters?.first)
}

-Thorsten 

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


Re: [swift-evolution] [Pitch]: Require parenthesis for ternary operator '?:' or change its priority

2016-09-03 Thread Xiaodi Wu via swift-evolution
I agree with Thorsten. I would expand on that by arguing that (1) the
original motivation identified is inapplicable to Swift; (2) the solution
doesn't solve the problem, and creates more problems; (3) the revised
solutions are not compatible with the direction of Swift.

Argument (1):

The only real-world example provided is one in C, not Swift. The key
difference is that C will implicitly cast from many types to bool, but
Swift does not. Therefore, that example is not a demonstration of a
weakness in Swift.

The same issue could only arise in Swift when you have an expression `a
[operator] b ? c : d` where a, b, c, and d are all Bool--and the operator
is a Boolean operator. I see no evidence that confusion is encountered in
everyday practice because the user would have to (a) not know the relative
precedence of Boolean/ternary operators; (b) incorrectly believe that they
do know the relative precedence of Boolean/ternary operators; and (c)
choose not to use parentheses.

I don't think it's likely you'll encounter a real-life example of this, nor
do I think that we should make source-breaking changes to the language to
prevent that possibility, because the category of errors that are possible
if a user doesn't understand something *and* affirmatively believes
something that's not true *and* chooses not to use a sane coding style is
infinite and impossible to defend against.

Argument (2):

The original proposal is, in essence, to change `?:` to `()?:`, but that
does not solve the issue outlined above *and* silently breaks existing code
that uses the current operator correctly. For instance, `a && (b || c) ? d
: e` would have a different meaning. Unless I'm mistaken, the only way to
remove all ambiguity is to change the syntax from `?:` to `(()?:)`, which I
think you'll agree is absurd.

Argument (3):

Changing the syntax to use words is a commonly rejected proposal, and I
don't see any new information on how it would solve this particular issue.
Although custom operators can't use words, built-in ones do (e.g., `as`)
and still have relative precedence that is higher than some other
operators. Therefore, spelling out "then" absolutely does not "carry the
meaning of low priority." In fact, by moving away from C, you are now going
to raise questions for the large proportion of uses who *do* know the
precedence of ?: as to what the corresponding precedence might be in Swift.

Finally, the argument to remove precedence here has the same defect as
previous proposals on changing or removing operator precedence. This
operator, like others, does have a known precedence. It is clearly written
out in a table, and in the case of `?:` it is essentially unchanged from
other languages in the C family. If you use the operator assuming it has
precedence that it does not have, then you are in for a bad time. However,
*every* operator with a precedence relationship has this "caveat". That is,
after all, what it means to have precedence above some operator and below
some other operator. If you believe that the issues described above are
sufficient to remove precedence for `?:`, you must also believe that it is
sufficient to remove relative precedence between any two operators except
the basic arithmetic operators `+`, `-`, `*`, `/`. But this is clearly not
the direction of Swift, since we have recently changed custom operator
syntax specifically to enable a better way to define new operators *with
custom precedence*.

In short, any change in Swift should be justified by a real-world use case.
A source-breaking change, such as modifying the syntax or precedence of an
existing operator, should be justified by an overwhelming compelling
real-world use case. I see only theoretical ones presented here, and I see
no solution that actually addresses the alleged issue in a way that fits
with the direction of Swift.


On Sat, Sep 3, 2016 at 7:29 AM Anton Zhilin via swift-evolution <
swift-evolution@swift.org> wrote:

> With the replacement, I would prefer just "then-else", which would still
> clearly carry the meaning of low priority. But yes, this option was
> explicitly rejected. Unfortunately.
>
> I also agree that changing the priority is not a solution. But how about
> removing priority?
>
> The following expression:
> `s << (x == 10) ? "10" : "not 10"`
> Is currently parsed as
> `(s << (x == 10)) ? "10" : "not 10"`
>
> With such a change, the compiler would make you add outer parentheses and
> find a bug, by the way:
> `s << ((x == 10) ? "10" : "not 10")`
>
> Should this apply to assignment operators?
> `s += (x == 10) ? "10" : "not 10"  // error?`
>
> I think such caveats of `?:` are worth creating a proposal, at least.
>
> 2016-09-03 14:21 GMT+03:00 Thorsten Seitz via swift-evolution <
> swift-evolution@swift.org>:
>
>> The problem you describe is not the priority of the ternary operator but
>> that developers just assume a priority without checking (or learning)
>> whether their assumption is correct. Changing the priority w

Re: [swift-evolution] [Review] SE-0140: Bridge Optional As Its Payload Or NSNull

2016-09-03 Thread Charlie Monroe via swift-evolution
The issue is that when the method doesn't immediately use the values of the 
array (e.g. stores it for later, or even worse passes them on to another 
object), the crash appears much later in the program with a message that NSNull 
doesn't respond to some selector - and that's often hard to debug.

On the other hand, I agree that it's better to use NSNull than how it currently 
works since this is a valid Swift 3 code:

let arr: [String?] = ["Hello", nil]
NSArray(array: arr)

that will not crash and will produce a valid NSArray. As Douglas Gregor 
mentioned earlier:

> […] because any Swift type can be placed in an Any, and anything can be 
> bridged to Objective-C. Nearly all of the concerns in this thread are about 
> this aspect of the already-accepted-and-implemented SE-0116: that an optional 
> can get passed through to an Objective-C ‘id’ without being explicitly 
> unwrapped. That behavior exists, and the type of the object seen in 
> Objective-C is an opaque Swift wrapper type. 

Playground will show the NSArray as two NSObjects (which are in fact 
_SwiftValue), which means that the ObjC will crash as well, but with even a 
more obscure message:

Attempted to dereference an invalid ObjC Object or send it an unrecognized 
selector.

So, choosing between two evils, I personally vote +1 for adding the NSNull 
bridging...



> On Sep 3, 2016, at 10:01 AM, Pyry Jahkola via swift-evolution 
>  wrote:
> 
> I don't feel confident enough about the Swift–Obj-C interop to cast my own 
> vote but I'd like to question this sentiment:
> 
>> On 03 Sep 2016, at 03:17, Charles Srstka via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> With the existing behavior, such mistakes are immediately obvious as 
>> Objective-C receives an opaque object that it cannot use (and probably soon 
>> crashes), so they are unlikely to make it past QA testing.
> 
> How is this different with NSNull though? If the callee expects an array of 
> NSNumbers for example and uses them (for anything more specific than 
> NSObject), the first NSNull instance will throw an NSInvalidArgumentException 
> basically crashing the program as well:
> 
> $ cat example.m
> @import Foundation;
> 
> int main() {
> id number = NSNull.null;
> NSLog(@"%ld", [number integerValue]);
> }
> 
> $ clang -fmodules example.m -o example && ./example
> 2016-09-03 10:47:21.822 example[31488:151700] -[NSNull integerValue]: 
> unrecognized selector sent to instance 0x7fff78561780
> (snip...)
> libc++abi.dylib: terminating with uncaught exception of type NSException
> Abort trap: 6
> 
> OTOH, if the only thing the Obj-C code planned to do was immediately convert 
> the NSArray into JSON, then a previously crashing example would now start 
> producing a JSON array with mixed numbers and nulls. But is that kind of code 
> likely in practice?
> 
> It would be different though if NSNull just swallowed any messages it 
> receives like `nil` does. There are 3rd party examples 
>  of 
> that behaviour, and that would be detrimental to code quality in the case of 
> Swift interop.
> 
> — Pyry
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Review] SE-0138 UnsafeBytes

2016-09-03 Thread Xiaodi Wu via swift-evolution
+1 as well. I would love to have Data.withUnsafeBytes use this type, and I
agree that UnsafeBytes and Data have orthogonal and not overlapping use
cases.
On Sat, Sep 3, 2016 at 08:59 gs. via swift-evolution <
swift-evolution@swift.org> wrote:

> +1
>
> I think that 'Unsafe' is fine because the mutable variant is definitely
> unsafe.
>
> I have some audio related code that would benefit greatly from this
> addition so I am all for it.
>
> TJ
>
> > On Sep 1, 2016, at 12:10, Dave Abrahams via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> >
> > Hello Swift community,
> >
> > The review of "UnsafeBytes" begins now and runs through September
> > 7th. This late addition to Swift 3 is a follow-up to SE-0107:
> > UnsafeRawPointer. It addresses common use cases for UnsafeRawPointer,
> > allowing developers to continue working with collections of UInt8 values,
> > but now doing so via a type safe API. The UnsafeBytes API will not
> require
> > direct manipulation of raw pointers or reasoning about binding memory.
> >
> > The proposal is available here:
> >
> > <
> https://github.com/apple/swift-evolution/blob/master/proposals/0138-unsafebytes.md
> >
> >
> > Reviews are an important part of the Swift evolution process. All reviews
> > should be sent to the swift-evolution mailing list at
> >
> > 
> >
> > or, if you would like to keep your feedback private, directly to the
> > review manager. When replying, please try to keep the proposal link at
> > the top of the message:
> >
> > Proposal link:
> > 
> >
> > What goes into a review?
> >
> > The goal of the review process is to improve the proposal under review
> > through constructive criticism and, eventually, determine the direction
> of
> > Swift. When writing your review, here are some questions you might want
> to
> > answer in your review:
> >
> > * What is your evaluation of the proposal?
> > * Is the problem being addressed significant enough to warrant a
> >   change to Swift?
> > * Does this proposal fit well with the feel and direction of Swift?
> > * If you have used other languages or libraries with a similar
> >   feature, how do you feel that this proposal compares to those?
> > * How much effort did you put into your review? A glance, a quick
> >   reading, or an in-depth study?
> >
> > More information about the Swift evolution process is available at
> >
> > 
> >
> > Thank you,
> >
> > -Dave Abrahams
> > Review Manager
> > ___
> > swift-evolution mailing list
> > swift-evolution@swift.org
> > https://lists.swift.org/mailman/listinfo/swift-evolution
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0138 UnsafeBytes

2016-09-03 Thread gs. via swift-evolution
+1 

I think that 'Unsafe' is fine because the mutable variant is definitely unsafe. 

I have some audio related code that would benefit greatly from this addition so 
I am all for it.

TJ 

> On Sep 1, 2016, at 12:10, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> Hello Swift community,
> 
> The review of "UnsafeBytes" begins now and runs through September
> 7th. This late addition to Swift 3 is a follow-up to SE-0107:
> UnsafeRawPointer. It addresses common use cases for UnsafeRawPointer,
> allowing developers to continue working with collections of UInt8 values,
> but now doing so via a type safe API. The UnsafeBytes API will not require 
> direct manipulation of raw pointers or reasoning about binding memory.
> 
> The proposal is available here:
> 
> 
> 
> Reviews are an important part of the Swift evolution process. All reviews
> should be sent to the swift-evolution mailing list at
> 
> 
> 
> or, if you would like to keep your feedback private, directly to the
> review manager. When replying, please try to keep the proposal link at
> the top of the message:
> 
> Proposal link:
> 
> 
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review
> through constructive criticism and, eventually, determine the direction of
> Swift. When writing your review, here are some questions you might want to
> answer in your review:
> 
> * What is your evaluation of the proposal?
> * Is the problem being addressed significant enough to warrant a
>   change to Swift?
> * Does this proposal fit well with the feel and direction of Swift?
> * If you have used other languages or libraries with a similar
>   feature, how do you feel that this proposal compares to those?
> * How much effort did you put into your review? A glance, a quick
>   reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at
> 
> 
> 
> Thank you,
> 
> -Dave Abrahams
> Review Manager
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch]: Require parenthesis for ternary operator '?:' or change its priority

2016-09-03 Thread Anton Zhilin via swift-evolution
With the replacement, I would prefer just "then-else", which would still
clearly carry the meaning of low priority. But yes, this option was
explicitly rejected. Unfortunately.

I also agree that changing the priority is not a solution. But how about
removing priority?

The following expression:
`s << (x == 10) ? "10" : "not 10"`
Is currently parsed as
`(s << (x == 10)) ? "10" : "not 10"`

With such a change, the compiler would make you add outer parentheses and
find a bug, by the way:
`s << ((x == 10) ? "10" : "not 10")`

Should this apply to assignment operators?
`s += (x == 10) ? "10" : "not 10"  // error?`

I think such caveats of `?:` are worth creating a proposal, at least.

2016-09-03 14:21 GMT+03:00 Thorsten Seitz via swift-evolution <
swift-evolution@swift.org>:

> The problem you describe is not the priority of the ternary operator but
> that developers just assume a priority without checking (or learning)
> whether their assumption is correct. Changing the priority won't solve that
> problem, it would only shift the problem over to those developers assuming
> the other priority. Worse, it would create this problem for those
> developers knowing the correct priority, because they now have to relearn
> the new priority with the added difficulty of the priority being different
> from C.
>
> I'm not sure whether the problem really is one (other operators have
> priorities too, which have to be learned), but assuming for the moment that
> it is, a solution would be to replace the ternary operator with an
> if-expression: *if* condition *then* expr1 *else* expr2
> This would enclose the condition between two keywords and thereby be free
> of misunderstandings.
> Replacing the ternary operator is on the commonly asked changes list,
> though, and therefore requires new arguments/insights why a replacement
> would make sense. I think the possibly confusing priority has been
> discussed already in the past and therefore wouldn't count as new insight,
> though I'm not quite sure.
>
> -Thorsten
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch]: Require parenthesis for ternary operator '?:' or change its priority

2016-09-03 Thread David Sweeris via swift-evolution
I don't he's proposing to change the precedence of "?:" per se, just requiring 
— as part of its syntax — it to be enclosed in parens when it's not by itself:

x = condition ? y : z //ok, since it's by itself
x = (test || condition) ? y : z //ok, since it's still technically by itself
x = test || (condition ? y : z) //ok, has parens
x = test || condition ? y : z //syntax error, no parens

I don't actually know what the correct precedence for ?: is because I never use 
that 4th "form", for the very reason this change is being proposed: it's too 
easy for me to get mixed up otherwise.

Where was I? Oh, right, as I understand it, this doesn't so much change ?:'s 
precedence as it does remove it from the precedence "system".

- Dave Sweeris

Sent from my iPhone, without sleep.

> On Sep 3, 2016, at 06:21, Thorsten Seitz via swift-evolution 
>  wrote:
> 
> The problem you describe is not the priority of the ternary operator but that 
> developers just assume a priority without checking (or learning) whether 
> their assumption is correct. Changing the priority won't solve that problem, 
> it would only shift the problem over to those developers assuming the other 
> priority. Worse, it would create this problem for those developers knowing 
> the correct priority, because they now have to relearn the new priority with 
> the added difficulty of the priority being different from C.
> 
> I'm not sure whether the problem really is one (other operators have 
> priorities too, which have to be learned), but assuming for the moment that 
> it is, a solution would be to replace the ternary operator with an 
> if-expression: if condition then expr1 else expr2
> This would enclose the condition between two keywords and thereby be free of 
> misunderstandings.
> Replacing the ternary operator is on the commonly asked changes list, though, 
> and therefore requires new arguments/insights why a replacement would make 
> sense. I think the possibly confusing priority has been discussed already in 
> the past and therefore wouldn't count as new insight, though I'm not quite 
> sure.
> 
> -Thorsten 
> 
>> Am 03.09.2016 um 11:34 schrieb Vladimir.S via swift-evolution 
>> :
>> 
>> (Seems my first email was not resent by mailing list due to its temporary 
>> problems. So second attempt)
>> 
>> I'm not sure if it is a correct time to discuss this, if not - I'll hold 
>> this for later time.
>> 
>> I was reading the article of author of some C/C++ static code analyzer tool 
>> where he was analyzing and discussing about code of some open source 
>> program. And there was a paragraph about bugs people make when using ternary 
>> operator. There a lot of bugs in C/C++ sources of well-known open source 
>> programs(like Chromium, ReactOS, MongoDB, Unreal Engine 4, Wine, FreeBSD 
>> Kernel and many others) made when developer assumes that priority of '?:' 
>> operator is higher than other operators like '+', '*', '|', '&' and other.
>> 
>> Examples:
>> 
>> int edge_height = titlebar_bottom->height() -
>>ShouldShowClientEdge() ? kClientEdgeThickness : 0;
>> 
>> ULONG treg = 0x54 + (dev < 3) ? (dev << 1) : 7;
>> 
>> if (IP_PACKET_SIZE < parsedPacket.info.H263.dataLength +
>>   parsedPacket.info.H263.insert2byteStartCode ? 2:0) {...}
>> 
>> stringstream ss;
>> ss << (sizeof(char *) == 8) ? " 64bit" : " 32bit";
>> 
>> return UniformVectorExpressions.GetAllocatedSize()
>>  + UniformScalarExpressions.GetAllocatedSize()
>>  + Uniform2DTextureExpressions.GetAllocatedSize()
>>  + UniformCubeTextureExpressions.GetAllocatedSize()
>>  + ParameterCollections.GetAllocatedSize()
>>  + UniformBufferStruct
>>  ?
>>  (sizeof(FUniformBufferStruct) +
>>   UniformBufferStruct->GetMembers().GetAllocatedSize())
>>  :
>>  0;
>> 
>> .. and so on..
>> 
>> Yes, in Swift we have no problem with mixing lets say Ints and Boolean 
>> values. But, it seems that it is highly possible to catch the same kind of 
>> problem with ternary operator in Swift for boolean values:
>> 
>> func isOne()->Bool { print(1); return false }
>> func isTwo()->Bool { print(2); return false }
>> 
>> let a = true
>> let b = true
>> 
>> let result = a || (b) ? isOne() : isTwo() // prints 1
>> 
>> print(result) // false
>> 
>> As you understand, to work correctly we need parentheses:
>> let result = a || ((b) ? isOne() : isTwo()) // 
>> print(result) // true
>> 
>> ..or set priority of '?:' operator higher than other operators (but this 
>> probably could *silently* break old code?)
>> 
>> I was trying to play with custom operators and ternary operator :
>> 
>> func <<(lhs: inout String, rhs: String) { lhs += rhs }
>> func <<(lhs: inout String, rhs: Bool) { lhs += rhs.description }
>> 
>> let x = 10
>> var s = ""
>> 
>> s << "abc"
>> print(s) // abc
>> 
>> s << (x == 10) ? "10" : "not 10"
>> print(s)
>> 
>> .. but this crashes the compiler(bug reported), but this shows that could be 
>> other ways when ternary operator works

Re: [swift-evolution] [Pitch]: Require parenthesis for ternary operator '?:' or change its priority

2016-09-03 Thread Thorsten Seitz via swift-evolution
The problem you describe is not the priority of the ternary operator but that 
developers just assume a priority without checking (or learning) whether their 
assumption is correct. Changing the priority won't solve that problem, it would 
only shift the problem over to those developers assuming the other priority. 
Worse, it would create this problem for those developers knowing the correct 
priority, because they now have to relearn the new priority with the added 
difficulty of the priority being different from C.

I'm not sure whether the problem really is one (other operators have priorities 
too, which have to be learned), but assuming for the moment that it is, a 
solution would be to replace the ternary operator with an if-expression: if 
condition then expr1 else expr2
This would enclose the condition between two keywords and thereby be free of 
misunderstandings.
Replacing the ternary operator is on the commonly asked changes list, though, 
and therefore requires new arguments/insights why a replacement would make 
sense. I think the possibly confusing priority has been discussed already in 
the past and therefore wouldn't count as new insight, though I'm not quite sure.

-Thorsten 

> Am 03.09.2016 um 11:34 schrieb Vladimir.S via swift-evolution 
> :
> 
> (Seems my first email was not resent by mailing list due to its temporary 
> problems. So second attempt)
> 
> I'm not sure if it is a correct time to discuss this, if not - I'll hold this 
> for later time.
> 
> I was reading the article of author of some C/C++ static code analyzer tool 
> where he was analyzing and discussing about code of some open source program. 
> And there was a paragraph about bugs people make when using ternary operator. 
> There a lot of bugs in C/C++ sources of well-known open source programs(like 
> Chromium, ReactOS, MongoDB, Unreal Engine 4, Wine, FreeBSD Kernel and many 
> others) made when developer assumes that priority of '?:' operator is higher 
> than other operators like '+', '*', '|', '&' and other.
> 
> Examples:
> 
> int edge_height = titlebar_bottom->height() -
>ShouldShowClientEdge() ? kClientEdgeThickness : 0;
> 
> ULONG treg = 0x54 + (dev < 3) ? (dev << 1) : 7;
> 
> if (IP_PACKET_SIZE < parsedPacket.info.H263.dataLength +
>   parsedPacket.info.H263.insert2byteStartCode ? 2:0) {...}
> 
> stringstream ss;
> ss << (sizeof(char *) == 8) ? " 64bit" : " 32bit";
> 
> return UniformVectorExpressions.GetAllocatedSize()
>  + UniformScalarExpressions.GetAllocatedSize()
>  + Uniform2DTextureExpressions.GetAllocatedSize()
>  + UniformCubeTextureExpressions.GetAllocatedSize()
>  + ParameterCollections.GetAllocatedSize()
>  + UniformBufferStruct
>  ?
>  (sizeof(FUniformBufferStruct) +
>   UniformBufferStruct->GetMembers().GetAllocatedSize())
>  :
>  0;
> 
> .. and so on..
> 
> Yes, in Swift we have no problem with mixing lets say Ints and Boolean 
> values. But, it seems that it is highly possible to catch the same kind of 
> problem with ternary operator in Swift for boolean values:
> 
> func isOne()->Bool { print(1); return false }
> func isTwo()->Bool { print(2); return false }
> 
> let a = true
> let b = true
> 
> let result = a || (b) ? isOne() : isTwo() // prints 1
> 
> print(result) // false
> 
> As you understand, to work correctly we need parentheses:
> let result = a || ((b) ? isOne() : isTwo()) // 
> print(result) // true
> 
> ..or set priority of '?:' operator higher than other operators (but this 
> probably could *silently* break old code?)
> 
> I was trying to play with custom operators and ternary operator :
> 
> func <<(lhs: inout String, rhs: String) { lhs += rhs }
> func <<(lhs: inout String, rhs: Bool) { lhs += rhs.description }
> 
> let x = 10
> var s = ""
> 
> s << "abc"
> print(s) // abc
> 
> s << (x == 10) ? "10" : "not 10"
> print(s)
> 
> .. but this crashes the compiler(bug reported), but this shows that could be 
> other ways when ternary operator works not as expected by many developers.
> 
> I believe the problem is worth to be discussed and probably solved for Swift 
> in near future.
> 
> Opinions?
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] [Pitch]: Require parenthesis for ternary operator '?:' or change its priority

2016-09-03 Thread Vladimir.S via swift-evolution
(Seems my first email was not resent by mailing list due to its temporary 
problems. So second attempt)


I'm not sure if it is a correct time to discuss this, if not - I'll hold 
this for later time.


I was reading the article of author of some C/C++ static code analyzer tool 
where he was analyzing and discussing about code of some open source 
program. And there was a paragraph about bugs people make when using 
ternary operator. There a lot of bugs in C/C++ sources of well-known open 
source programs(like Chromium, ReactOS, MongoDB, Unreal Engine 4, Wine, 
FreeBSD Kernel and many others) made when developer assumes that priority 
of '?:' operator is higher than other operators like '+', '*', '|', '&' and 
other.


Examples:

int edge_height = titlebar_bottom->height() -
ShouldShowClientEdge() ? kClientEdgeThickness : 0;

ULONG treg = 0x54 + (dev < 3) ? (dev << 1) : 7;

if (IP_PACKET_SIZE < parsedPacket.info.H263.dataLength +
   parsedPacket.info.H263.insert2byteStartCode ? 2:0) {...}

stringstream ss;
ss << (sizeof(char *) == 8) ? " 64bit" : " 32bit";

return UniformVectorExpressions.GetAllocatedSize()
  + UniformScalarExpressions.GetAllocatedSize()
  + Uniform2DTextureExpressions.GetAllocatedSize()
  + UniformCubeTextureExpressions.GetAllocatedSize()
  + ParameterCollections.GetAllocatedSize()
  + UniformBufferStruct
  ?
  (sizeof(FUniformBufferStruct) +
   UniformBufferStruct->GetMembers().GetAllocatedSize())
  :
  0;

.. and so on..

Yes, in Swift we have no problem with mixing lets say Ints and Boolean 
values. But, it seems that it is highly possible to catch the same kind of 
problem with ternary operator in Swift for boolean values:


func isOne()->Bool { print(1); return false }
func isTwo()->Bool { print(2); return false }

let a = true
let b = true

let result = a || (b) ? isOne() : isTwo() // prints 1

print(result) // false

As you understand, to work correctly we need parentheses:
let result = a || ((b) ? isOne() : isTwo()) // 
print(result) // true

..or set priority of '?:' operator higher than other operators (but this 
probably could *silently* break old code?)


I was trying to play with custom operators and ternary operator :

func <<(lhs: inout String, rhs: String) { lhs += rhs }
func <<(lhs: inout String, rhs: Bool) { lhs += rhs.description }

let x = 10
var s = ""

s << "abc"
print(s) // abc

s << (x == 10) ? "10" : "not 10"
print(s)

.. but this crashes the compiler(bug reported), but this shows that could 
be other ways when ternary operator works not as expected by many developers.


I believe the problem is worth to be discussed and probably solved for 
Swift in near future.


Opinions?

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


Re: [swift-evolution] [Review] SE-0140: Bridge Optional As Its Payload Or NSNull

2016-09-03 Thread Pyry Jahkola via swift-evolution
I don't feel confident enough about the Swift–Obj-C interop to cast my own vote 
but I'd like to question this sentiment:

> On 03 Sep 2016, at 03:17, Charles Srstka via swift-evolution 
>  wrote:
> 
> With the existing behavior, such mistakes are immediately obvious as 
> Objective-C receives an opaque object that it cannot use (and probably soon 
> crashes), so they are unlikely to make it past QA testing.

How is this different with NSNull though? If the callee expects an array of 
NSNumbers for example and uses them (for anything more specific than NSObject), 
the first NSNull instance will throw an NSInvalidArgumentException basically 
crashing the program as well:

$ cat example.m
@import Foundation;

int main() {
id number = NSNull.null;
NSLog(@"%ld", [number integerValue]);
}

$ clang -fmodules example.m -o example && ./example
2016-09-03 10:47:21.822 example[31488:151700] -[NSNull integerValue]: 
unrecognized selector sent to instance 0x7fff78561780
(snip...)
libc++abi.dylib: terminating with uncaught exception of type NSException
Abort trap: 6

OTOH, if the only thing the Obj-C code planned to do was immediately convert 
the NSArray into JSON, then a previously crashing example would now start 
producing a JSON array with mixed numbers and nulls. But is that kind of code 
likely in practice?

It would be different though if NSNull just swallowed any messages it receives 
like `nil` does. There are 3rd party examples 
 of 
that behaviour, and that would be detrimental to code quality in the case of 
Swift interop.

— Pyry

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