Re: [swift-users] struct property changing calls didSet of the Struct each time, but class won't

2017-11-13 Thread Guillaume Lessard via swift-users
In your example, when `Foo` is a class, then `A` does not see a mutation since 
the storage is out-of-line. When `Foo` is a struct, it is stored in-line and a 
mutation does mutate `A`.

In other words, when what’s stored in `A` is a reference, the reference itself 
does not get mutated when you mutate your `Foo`. If you change the statement in 
your loop to `a.foo = Foo()`, you’ll see that the `didSet` gets invoked again.

Cheers,
Guillaume Lessard

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


Re: [swift-users] Why does the withUnsafeMutableBufferPointer closure take an inout parameter?

2017-10-14 Thread Guillaume Lessard via swift-users

> On Oct 14, 2017, at 10:29, Braden Scothern via swift-users 
>  wrote:
> 
> There is a lot of value in these being mutating functions when working with C 
> APIs that need a buffer for it to write to.
> 
> If you have a collection and ensure it had allocated it's memory, you can 
> then have the C API write directly into the collection's storage avoiding 
> extra copy operations.
> 
> I personally take advantage of this a lot. Because I'm wrapping a C library 
> in Swift as part of my work.
> 
> If this was changed to only non mutating functions, it still wouldn't be able 
> to guarantee that the buffer isn't mutating the collection without always 
> doing a deep copy. It is very easy to go from an UnsafeBufferPointer -> 
> UnsafeMutableBufferPointer and have people change things.

The types wouldn’t change, just whether the method is marked `mutating`.

The reason I have doubts whether it’s worth it is that even if the 
implementation gets duplicated as non-mutating, it won’t prevent cases where a 
{*}BufferPointer needs to be a var: whenever it is passed into a generic 
MutableCollection context, it will need to be a var in order to be usable.
Is it worth it?

Cheers,
Guillaume Lessard

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


Re: [swift-users] Why does the withUnsafeMutableBufferPointer closure take an inout parameter?

2017-10-12 Thread Guillaume Lessard via swift-users
It’s not a bug-fix and it is an API change, so it seems it would have to go 
through evolution.

Guillaume Lessard

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


Re: [swift-users] Why does the withUnsafeMutableBufferPointer closure take an inout parameter?

2017-10-11 Thread Guillaume Lessard via swift-users
A lot of the MutableCollection implementation is in protocol extensions 
(swapAt, for example.)

Should an additional version be written just for the Unsafe*BufferPointer types?

Guillaume Lessard

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


Re: [swift-users] UnsafeMutableRawPointer to UnsafeMutablePointer: EXC_BAD_ACCESS on pointee

2017-09-24 Thread Guillaume Lessard via swift-users
[re-sending to the list, and elaborating]

You are making the runtime use the first word of the referent as if it were the 
reference.

The lowercase-c variable is a reference. rawPointer contains the same value, 
and points to the beginning of the object data. Your typecasting is telling the 
runtime that pointer.pointee is a *reference*, but ‘pointer’ points to object 
data. The print statement attempts to dereference data that is not a pointer at 
all.

Consider this:

let badThingToDo = rawPointer.assumingMemoryBound(to: Int.self)[2] // contains 
42

The first word at rawPointer is type data, the second has reference counts (or 
the side table pointer), the third has the first word of instance data.

Note that c is alive, and Unmanaged’s implementation is fine (we wouldn’t have 
made it this far if it weren’t).

Guillaume Lessard


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


Re: [swift-users] RSS feed for the Swift.org blog not working

2017-09-20 Thread Guillaume Lessard via swift-users
% wget http://swift.org/atom.xml
URL transformed to HTTPS due to an HSTS policy
[snip]

HSTS -> https://tools.ietf.org/html/rfc6797

swift.org has simply become inaccessible to non-secure or misconfigured clients.

GL

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


Re: [swift-users] Simultaneous access to global tuple members

2017-08-08 Thread Guillaume Lessard via swift-users

> On Aug 8, 2017, at 09:10, Martin R  wrote:
> 
> In that example the tuple is a (stored) property of a class, not a global 
> variable. And why does it crash for a global variable, but not for a local 
> variable in a function?

In the case of a local variable in a function, the compiler can statically 
prove that there is no simultaneous access, and using `swap` is allowed. With a 
global variable, the compiler can’t statically prove exclusive access.
(it seems silly with your simple example, but the system doesn’t try static 
enforcement with global variables.)

Here’s another modification which traps at runtime:

***
import Dispatch

func foo()  {
  var tuple = (1, 2)

  let q = DispatchQueue(label: "queue")
  q.async { swap(, ) }
  q.sync {}

  print(tuple)
}

foo()
***

Guillaume Lessard

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


Re: [swift-users] Simultaneous access to global tuple members

2017-08-08 Thread Guillaume Lessard via swift-users

> On Aug 8, 2017, at 01:11, Martin R via swift-users  
> wrote:
> 
> SE-0176 Enforce Exclusive Access to Memory 
> (https://github.com/apple/swift-evolution/blob/master/proposals/0176-enforce-exclusive-access-to-memory.md)
>  states that "Accesses to different stored properties of a struct or 
> different elements of a tuple are allowed to overlap."
> 
> [snip]
> 
> Is there anything special with simultaneous access to members of a global 
> tuple, or is this a bug?

Not a bug. The very next sentence after the one you quoted: “However, note that 
modifying part of a value type still requires exclusive access to the entire 
value”. The first example in that section 
(https://github.com/apple/swift-evolution/blob/master/proposals/0176-enforce-exclusive-access-to-memory.md#value-types)
 is similar to your example; it trips the dynamic enforcement mechanism for the 
same reason. The second example shows a possible workaround.

Sincerely,
Guillaume Lessard

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


Re: [swift-users] Why inout protocol parameter in function work with strange

2017-05-26 Thread Guillaume Lessard via swift-users
In your example, the compiler needs a parameter of type Position. Car is a type 
of Position, but they are not interchangeable. See below:

> On May 26, 2017, at 00:33, Седых Александр via swift-users 
>  wrote:
> 
> protocol Position {
> var x: Double { getset }
> }
>  
> struct Car: Position {
> var x: Double
> }
>  
> func move(item: inout Position) {
> item.x += 1
> }
>  
> var car = Car(x: 50)

var pos: Position = car

move(item: )// this works.
assert(pos.x == 51) // works

The move function as you wrote it requires the memory representation of a 
Position variable, which Car does not have; when you assign it to a Position 
variable, the Car struct gets accessed through an indirection layer. (There was 
a WWDC talk about this last year or the year before.)

You may want a generic function instead:

func move(item: inout P) {
  item.x += 1
}

move(item: )// this works, since it’s now calling the generic function.
assert(car.x == 51) // works

Cheers,
Guillaume Lessard

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


Re: [swift-users] Annotating C APIs without changing the original header files

2017-05-13 Thread Guillaume Lessard via swift-users

> On May 12, 2017, at 12:33, Daniel Dunbar via swift-users 
>  wrote:
> 
> We don't have explicit support for api notes in SwiftPM.
> 

It would also be useful for cases when the latest versions of clang can’t be 
counted on for Linux deployments (3.6 is considered cutting-edge by some, heh)

Guillaume Lessard

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


Re: [swift-users] Atomics and Memory Fences in Swift

2017-05-04 Thread Guillaume Lessard via swift-users
It works now, but it's not correct. I wish there were a correct way available.

Guillaume Lessard

> On May 3, 2017, at 21:30, Colin Barrett via swift-users 
>  wrote:
> 
> I haven't used this in production, but this repository looks pretty 
> promising. It's more or less just wrapping up the clang atomic intrinsics 
> into a Swift package.
> 
> https://github.com/glessard/swift-atomics
> 
> -Colin
> 
>> On Mon, May 1, 2017 at 12:43 PM Joe Groff via swift-users 
>>  wrote:
>> 
>> > On Apr 25, 2017, at 1:08 PM, Shawn Erickson  wrote:
>> >
>> >
>> > On Mon, Dec 5, 2016 at 9:28 AM Joe Groff via swift-users 
>> >  wrote:
>> >
>> >> On Dec 4, 2016, at 4:53 PM, Andrew Trick via swift-users 
>> >>  wrote:
>> >>
>> >>
>> >>> On Nov 30, 2016, at 5:40 AM, Anders Ha via swift-users 
>> >>>  wrote:
>> >>>
>> >>> Hi guys
>> >>>
>> >>> I have recently started adopting lock-free atomics with memory fences, 
>> >>> but it seems Swift at this moment does not have any native instruments.
>> >>>
>> >>> Then I read a thread in the Apple Developer Forum 
>> >>> (https://forums.developer.apple.com/thread/49334), which an Apple staff 
>> >>> claimed that all imported atomic operations are "not guaranteed to be 
>> >>> atomic". But for my tests with all optimizations enabled (-Owholemodule 
>> >>> and -O), the OSAtomic primitives and stdatomic fences do not seem going 
>> >>> wild.
>> >>>
>> >>> Is these `atomic_*` and `OSAtomic*` primitives really unsafe in Swift as 
>> >>> claimed? It doesn't seem like the Swift compiler would reorder memory 
>> >>> accesses around a C function call that it wouldn't be able to see 
>> >>> through.
>> >>
>> >> Did you get an answer to this? I’m not sure what led you to believe the 
>> >> primitives are unsafe in Swift. Importing them doesn’t change their 
>> >> semantics.
>> >
>> > If you apply them to memory you allocated manually with malloc/free on 
>> > UnsafeMutablePointer's allocation methods, then yeah, they should work as 
>> > they do in C. That's the safest way to use these functions today. Passing 
>> > a Swift `var` inout to one of these functions does not guarantee that 
>> > accesses to that var will maintain atomicity, since there may be bridging 
>> > or reabstracting conversions happening under the hood.
>> >
>> > -Joe
>> >
>> > Is the following in the ball park of being correct (going back over some 
>> > old code we have)...
>> >
>> > public struct AtomicBool {
>> >
>> > private static let bitLocation: UInt32 = 0
>> > private static let trueValue: UInt8 = 0x80
>> > private static let falseValue: UInt8 = 0x00
>> >
>> > private let value = UnsafeMutablePointer.allocate(capacity: 1) 
>> > // TODO - leaking right? How to deal with that in a struct situation...?
>> > public var onSet: ((_ old: Bool, _ new: Bool) -> ())?
>> >
>> > public init(_ intialValue: Bool = false) {
>> > value.initialize(to: intialValue ? AtomicBool.trueValue : 
>> > AtomicBool.falseValue)
>> > onSet = nil
>> > }
>> >
>> > public init(_ intialValue: Bool = false, onSet: ((_ old: Bool, _ new: 
>> > Bool) -> ())?) {
>> > value.initialize(to: intialValue ? AtomicBool.trueValue : 
>> > AtomicBool.falseValue)
>> > self.onSet = onSet
>> > }
>> >
>> > public mutating func set(_ newValue: Bool) {
>> > _ = getAndSet(newValue)
>> > }
>> >
>> > public mutating func getAndSet(_ newValue: Bool) -> Bool {
>> > let oldValue: Bool
>> > if newValue {
>> > oldValue = 
>> > Darwin.OSAtomicTestAndSetBarrier(AtomicBool.bitLocation, value)
>> > }
>> > else {
>> > oldValue = 
>> > Darwin.OSAtomicTestAndClearBarrier(AtomicBool.bitLocation, value)
>> > }
>> >
>> > onSet?(oldValue, newValue)
>> > return oldValue
>> > }
>> >
>> > public func get() -> Bool { // TODO - document the lazy "safety" 
>> > aspect of get
>> > return value.pointee != AtomicBool.falseValue
>> > }
>> 
>> That looks OK. It might be better to provide an allocate/deallocate or with 
>> { ... } interface instead of burying the allocate call in the initializer 
>> since the user will need to handle the deallocation of the buffer at some 
>> point.
>> 
>> -Joe
>> ___
>> swift-users mailing list
>> swift-users@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users
> ___
> swift-users mailing list
> swift-users@swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] weak self

2017-05-02 Thread Guillaume Lessard via swift-users

> On May 2, 2017, at 00:05, Rien  wrote:
> 
> Interesting: this is a kind-of symmetry break between optionals and weak 
> references.
> I.e. most (inexperienced?) programmers will see a strong similarity between 
> weak references and optionals.
> And for a lot of use cases they do indeed behave similar.
> But for weak references I think the guideline should be: Never ‘force-unwrap’ 
> it.
> Maybe this should be mentioned in the swift guide?
> Maybe even include a warning in the compiler for this?

I also don’t think there’s a symmetry break there. A weak reference is 
effectively a shared variable between threads, so its value can change between 
any two actions. This would be the same if it were an Optional that happens to 
be shared between threads, but you’d have to handle locking yourself. An `if 
let` binding to a strong reference is effectively a lightweight lock against 
deletion of your object.

The more critical thing is that if you need to perform more than one action 
with a weak reference, you really should bind it to a strong reference first. 
The optional chaining approach is a fine shortcut for a single action.

Cheers,
Guillaume Lessard

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


Re: [swift-users] Protocol conformance failure

2017-03-09 Thread Guillaume Lessard via swift-users

> On Mar 9, 2017, at 12:46, Edward Connell via swift-users 
>  wrote:
> 
> // Everything compiles fine until this
> someFunc(items: items)

This is a frequent pain point: protocol existentials cannot stand in for the 
protocol they represent.
Your function wants a concrete type that conforms to ItemProtocol, but an array 
of disparate types which happen to separately conform to ItemProtocol does not 
do that.

You will need to overload thusly:

func someFunc(items: [ItemProtocol]) {
  for item in items {
print(item.message)
  }
}

until, someday, this pain point is resolved.

Cheers,
Guillaume Lessard

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


Re: [swift-users] Ugliness bridging Swift String to char *

2017-03-06 Thread Guillaume Lessard via swift-users

> On Mar 6, 2017, at 12:28 AM, Kenny Leung via swift-users 
>  wrote:
> 
> Follow-up on this:
> 
> The StaticString solution doesn’t work:
> 
> let separator: StaticString = “|”
> opt.fieldSep = UnsafeMutablePointer(mutating: separator.utf8start)
> 
> … because utf8start returns UnsafePointer, and fieldSep is actually 
> UnsafeMutablePointer. There doesn’t seem to be any way to convert 
> UnsafePointer to UnsafePointer.

There is: .withMemoryRebound()

var opt = PQPrintOpt()
let sep2: StaticString = "|"
opt.fieldSep = sep2.utf8Start.withMemoryRebound(to: Int8.self, capacity: 
sep2.utf8CodeUnitCount) {
  buffer in
  let p = UnsafeMutablePointer.allocate(capacity: sep2.utf8CodeUnitCount)
  p.assign(from: buffer, count: sep2.utf8CodeUnitCount)
  return p
}

// use opt

opt.fieldSep.deinitialize(count: sep2.utf8CodeUnitCount)
opt.fieldSep.deallocate(capacity: sep2.utf8CodeUnitCount)

Cheers,
Guillaume Lessard

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


Re: [swift-users] Is this really a race condition?

2017-03-01 Thread Guillaume Lessard via swift-users

> On Mar 1, 2017, at 3:21 PM, Edward Connell via swift-users 
>  wrote:
> 
> The thread sanitizer on Linux is reporting that I have race conditions in 
> libswiftcore. I eliminated enough code down to this trivial example. Is there 
> really a race condition here or are these bogus errors?
> 
>   let count = 1000
>   var items = [[UInt8]?](repeating: nil, count: count)
> 
>   DispatchQueue.concurrentPerform(iterations: count) {
>   items[$0] = [UInt8](repeating: 7, count: 10)
>   }
> 
> My real scenario is retrieving data asynchronously, so I just threw in a 
> buffer assignment.

The assignments to array elements are where the race lies.

I don’t know about the libswiftcore part, but: assigning to a shared Array 
concurrently from multiple threads won't work, because of Array's copy-on-write 
behaviour. You could do

let items = UnsafeMutablePointer<[UInt8]?>.allocate(capacity: 1)
items.initialize(to: nil, count: count)

DispatchQueue.concurrentPerform(iterations: count) {
  items[$0].initialize([UInt8](repeating: 7, count: 10))
}

// you’ll be able to see here that they’re all initialized

items.deallocate(capacity: count)

Cheers,
Guillaume Lessard

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


Re: [swift-users] for in? optionalCollection {

2017-02-12 Thread Guillaume Lessard via swift-users
This could come for almost free after SE-0143 is implemented: an Optional of a 
Sequence could itself be made to conform to Sequence. It would cost no new 
syntax.

extension Optional: Sequence where Wrapped: Sequence {
  func makeIterator() -> AnyIterator {
switch self {
case .some(let sequence):
  return AnyIterator(sequence.makeIterator())
case .none:
  return AnyIterator { nil }
}
  }
}

This would be more easily done than new syntax, surely.

Cheers,
Guillaume Lessard

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


Re: [swift-users] Collection Oddities

2017-02-07 Thread Guillaume Lessard via swift-users

> On 7 févr. 2017, at 21:57, Slava Pestov <spes...@apple.com> wrote:
> 
>> 
>> On Feb 7, 2017, at 8:14 PM, Guillaume Lessard via swift-users 
>> <swift-users@swift.org> wrote:
>> 
>> I keep running into weird things with Swift 3 Collections.
>> 
>> A) Collection has its count property defined as an Int via IndexDistance:
>> 
>> public protocol Collection : Indexable, Sequence {
>>   associatedtype IndexDistance : SignedInteger = Int  // line 182 in 
>> Collection.swift
>>   public var count: IndexDistance { get } // line 776
>> }
> 
> This declaration specifies that the *default* associated type is Int, not 
> that it’s *always* Int. A Collection implementation is free to use a 
> different type as its IndexDistance if it wants.

I see how I’d misunderstood that line.

This being said, does this particular freedom really bring anything to the 
table? It is simply a counter (“the number of steps between a pair of 
indices”). On one hand, a “collection" that has in excess of Int.max/2 elements 
likely needs a different protocol; on the other, using a shorter type for a 
counter seems retro.

Thanks!
Guillaume Lessard

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


[swift-users] Collection Oddities

2017-02-07 Thread Guillaume Lessard via swift-users
I keep running into weird things with Swift 3 Collections.

A) Collection has its count property defined as an Int via IndexDistance:

public protocol Collection : Indexable, Sequence {
associatedtype IndexDistance : SignedInteger = Int  // line 182 in 
Collection.swift
public var count: IndexDistance { get } // line 776
}

Given this, why can’t `count` be treated as an Int?

func intCount(of c: C) -> Int {
  return c.count // nope!
}

A numericCast is required here in order to “convert” what is known-to-be-an-Int 
to an actual Int.
Why this is so? IndexDistance is defined such that it must be an integer (“A 
type that represents the number of steps between a pair of indices”)...
What is gained by making it so generic that it can’t simply be an Int?


B) Collection.Indices is a Collection of Index, *but*
- Collection.Indices.Index is not the same type as Collection.IndexDistance
- Collection.Indices.Iterator.Element is somehow not the automatically the same 
type as Collection.Index
(ugh)

The second seems like a conditional conformance issue, but the first one is 
baffling.

I did find that with String.CharacterView:
String.CharacterView.Indices.Index != String.CharacterView.IndexDistance
although, as expected,
String.CharacterView.Indices.IndexDistance == String.CharacterView.IndexDistance
(which provides an clear workaround.)


***
I wanted to extend Collection with concurrentPerform; which seems simple on the 
surface:

extension Collection {
  public func concurrentPerform(task: @escaping (Self.Iterator.Element) -> 
Void) {
DispatchQueue.concurrentPerform(iterations: count) {
  iteration in
  task(self[indices[iteration]])
}
  }
}
… but that won’t do.

The closest thing I found that does work is this:

extension Collection {
  public func concurrentPerform(task: @escaping (Self.Iterator.Element) -> 
Void) {
let count: Int = numericCast(self.count)
let indexList = (0..

Re: [swift-users] Confused/Surprised by IndexingIterator.forEach behavior

2016-12-28 Thread Guillaume Lessard via swift-users
forEach is defined by the Sequence protocol, and is not a mutating function. By 
definition, it must create a local iterator in order to perform its duty. As a 
consequence, the variable `stream` is the same immediately before and after the 
forEach call.

Cheers,
Guillaume Lessard

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


Re: [swift-users] Weird protocol behaviour.

2016-12-22 Thread Guillaume Lessard via swift-users
The function foo(x: A){} requires a type which conforms to protocol P.

An existential of protocol P does not actually conform to protocol P.
It’s always been a limitation in Swift: https://bugs.swift.org/browse/SR-55

If the function’s signature were foo(x: P){}, it would work.


Howard’s example swaps the protocol P for a concrete type (P1), which is what 
makes it work.

Cheers,
Guillaume Lessard

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