profile
viewpoint
Johannes Weiss weissi London, UK https://twitter.com/johannesweiss #SwiftNIO core team [on paternity leave until end of 2020]

apple/swift 54816

The Swift Programming Language

apple/swift-evolution 11773

This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.

apple/swift-package-manager 8129

The Package Manager for the Swift Programming Language

apple/swift-corelibs-foundation 4097

The Foundation Project, providing core utilities, internationalization, and OS independence

apple/swift-corelibs-xctest 871

The XCTest Project, A Swift core library for providing unit test support

weissi/FRLayeredNavigationController 493

FRLayeredNavigationController, an iOS container view controller that works like a stack of paper with an API similar to UINavigationController.

kylebrowning/APNSwift 368

An HTTP/2 APNS library built on swift-nio

swift-server/swift-service-lifecycle 202

Cleanly startup and shutdown server application, freeing resources in order before exiting.

swift-server/swift-backtrace 197

💥 Backtraces for Swift on Linux

MrLotU/SwiftPrometheus 51

Client side Prometheus library in Swift

CommitCommentEvent

Pull request review commentapple/swift-evolution

[Proposal Revision] Extend property wrappers to functions and closure parameters.

 func buy(  ## Detailed design -Property wrappers are essentially sugar wrapping a given declaration with compiler-synthesized code. This proposal retains this principle. Annotating a parameter declaration with a property-wrapper attribute allows the call-site to pass a wrapped value or a projected value, and the compiler will automatically initialize the backing wrapper to pass to the function. The function author can also use the property-wrapper syntax for accessing the backing wrapper and the projected value in the body of the function.+Property wrappers are essentially sugar wrapping a given declaration with compiler-synthesized code. Retaining this principle, a function can now be called with the wrapped and projected values. Namely, annotating a parameter declaration with a property-wrapper attribute changes the declaration’s type to the backing storage, and prompts the compiler to synthesize the wrapped and projected values. When the function is called the compiler will, also, insert a call to the appropriate property-wrapper initializer.

Ok, I see your point. Upon rereading the paragraph, I realize that expecting to hear about the current design (since it's in the section's name), I read about existing behavior, which is then paralleled to new behavior. I find this problematic because the reader will –– up to this point –– be unfamiliar with this new behavior. Thus, what do you think of simply moving the first two periods in the end?


Annotating a parameter declaration with a property-wrapper attribute allows the call-site to pass a wrapped value or a projected value, and the compiler will automatically initialize the backing wrapper to be passed to the function. The function author can also use the property-wrapper syntax for accessing the backing wrapper and the projected value within the body of the function. This behavior merely builds on property wrappers’ being sugar wrapping a given declaration with compiler-synthesized code.

filip-sakel

comment created time in 16 minutes

CommitCommentEvent

Pull request review commentapple/swift-evolution

[Proposal Revision] Extend property wrappers to functions and closure parameters.

 func buy(  ## Detailed design -Property wrappers are essentially sugar wrapping a given declaration with compiler-synthesized code. This proposal retains this principle. Annotating a parameter declaration with a property-wrapper attribute allows the call-site to pass a wrapped value or a projected value, and the compiler will automatically initialize the backing wrapper to pass to the function. The function author can also use the property-wrapper syntax for accessing the backing wrapper and the projected value in the body of the function.+Property wrappers are essentially sugar wrapping a given declaration with compiler-synthesized code. Retaining this principle, a function can now be called with the wrapped and projected values. Namely, annotating a parameter declaration with a property-wrapper attribute changes the declaration’s type to the backing storage, and prompts the compiler to synthesize the wrapped and projected values. When the function is called the compiler will, also, insert a call to the appropriate property-wrapper initializer.

I think these changes have obscured the meaning/purpose of this paragraph.

Retaining this principle, a function can now be called with the wrapped and projected values

I don't think this makes sense without the context of "Annotating a parameter declaration with a property-wrapper attribute". Also, the fact that a function can be called with a wrapped value or a projected value of a property wrapper doesn't really follow from "retaining this principle"

annotating a parameter declaration with a property-wrapper attribute changes the declaration’s type to the backing storage

This isn't something we want to state unless we're explicitly talking about how the code is compiled. As far as the user is concerned, the function type does not take in the backing storage. That's why had worded the sentence to be about the call-site.

and prompts the compiler to synthesize the wrapped and projected values

The wrapped and projected values are not synthesized, they're provided by the user.

I'm not sure why this last sentence was removed:

The function author can also use the property-wrapper syntax for accessing the backing wrapper and the projected value in the body of the function

This is showcasing how the feature is useful for function authors because they now have property-wrapper syntax in the body of the function.

filip-sakel

comment created time in an hour

push eventapple/swift-evolution

Joe Groff

commit sha 753e81fad04f070a39df867f10ecab90fab84d49

begin review for SE-299

view details

push time in 2 hours

push eventgrpc/grpc-swift

George Barnett

commit sha b4bebe5000ff52b59c94090c3daca31c68257e4d

Support new handlers in the server codec + state machine (#1101) Motivation: We have new ways of handling RPCs on the server, the server codec and state machine should use them! Modifications: - In the state machine: try to handle an RPC using the new API, falling back to the old way - In the codec: store a mode, i.e. how we're handling the RPC. - Flushing has become the responsibility of the server codec (as opposed to the RPC-specific channel handler): now we only flush at the end of 'channelReadComplete' (if a flush is pending), or on calls to 'flush(context:)' if we aren't currently reading. Result: The server supports the new RPC handlers.

view details

push time in 3 hours

PR merged grpc/grpc-swift

Support new handlers in the server codec + state machine semver-patch •

Motivation:

We have new ways of handling RPCs on the server, the server codec and state machine should use them!

Modifications:

  • In the state machine: try to handle an RPC using the new API, falling back to the old way
  • In the codec: store a mode, i.e. how we're handling the RPC.
  • Flushing has become the responsibility of the server codec (as opposed to the RPC-specific channel handler): now we only flush at the end of 'channelReadComplete' (if a flush is pending), or on calls to 'flush(context:)' if we aren't currently reading.

Result:

The server supports the new RPC handlers.

+232 -87

0 comment

3 changed files

glbrntt

pr closed time in 3 hours

Pull request review commentapple/swift-evolution

[Proposal Revision] Extend property wrappers to functions and closure parameters.

 Property Wrappers were [introduced in Swift 5.1](https://github.com/apple/swift-  Property wrappers have undoubtably been very successful. Applying a property wrapper to a property is enabled by an incredibly lightweight and expressive syntax. For instance, frameworks such as [SwiftUI](https://developer.apple.com/documentation/swiftui/) and [Combine](https://developer.apple.com/documentation/combine) introduce property wrappers such as [`State`](https://developer.apple.com/documentation/swiftui/state), [`Binding`](https://developer.apple.com/documentation/swiftui/binding) and [`Published`](https://developer.apple.com/documentation/combine/published) to expose elaborate behavior through a succinct interface, helping craft expressive yet simple APIs. However, property wrappers are only applicable to local variables and type properties, shattering the illusion that they helped realize in the first place when working with parameters. -### Memberwise initialization+Property wrappers attached to parameters have a wide variety of use cases. We present a few examples here. -Currently, property-wrapper attributes on struct properties interact with function parameters through the struct's synthesized memberwise initializer. However, property-wrapper attributes are _not_ supported on function parameters. This leads to complicated and nuanced rules for which type, between the wrapped-value type and the backing property-wrapper type, the memberwise initializer accepts.+### Argument validation -The compiler will choose the wrapped-value type to offer a convenience to the call-site when the property wrapper has an initializer of the form `init(wrappedValue:)` accepting the wrapped-value type, as seen here:+Both library developers and language users often need to assert their assumptions, for which `precondition(_:_:)` is often used:  ```swift-import SwiftUI---struct TextEditor {--  @State var document: Optional<URL>-  +enum Product {+  case plainSandwich +  case grilledCheeseSandwich +  case avocadoToast } --func openEditor(with swiftFile: URL) -> TextEditor {-  TextEditor(document: swiftFile) -  // The wrapped type is accepted here.+func buy(quantity: Int, of product: Product) {+  precondition(quanity >= 1, "Invalid product quanity.")+  +  if quantity == 1 {+    ...+  } } ``` -However, this can take flexibility away from the call-site if the property wrapper has other `init` overloads, because the call-site _cannot_ choose a different initializer. Further, if the property wrapper is explicitly initialized via `init()`, then the memberwise initializer will choose the backing-wrapper type, even if the wrapper supports `init(wrappedValue:)`. This results in unnecessary boilerplate at call-sites that _do_ want to use `init(wrappedValue:)`:+The above code is quite clear; it has, though, the obvious drawback that changing the the condition to be asserted or its error message requires significant effort as a precondition statement is individually written for each function and manually documented.++Furthermore, supposing the above is library code, we may want to test for our precondition while offering an easy-to-debug way. So, using `Validation` from [`PropertyKit`](https://github.com/SvenTiigi/ValidatedPropertyKit) we can write:  ```swift-import SwiftUI+@propertyWrapper+struct Asserted<Value> {+  // The assertion will appear at the right file and line+  init(+    wrappedValue: Value, +    validation: Validation<Value>,+    file: StaticString = #file,+    line: UInt = #line+  ) {+    ...+  } +  var wrappedValue: Value { ... } -struct TextEditor {+  var projectedValue: Result<Value, ValidationResult> { ... }+} -  @State() var document: Optional<URL>++func buy(+  quantity: Int, +  of product: Product,+  file: StaticString = #file,+  line: UInt = #line+  // These are a lot of properties for every time+  // we want to check for the right quantity.+) {+  var validatedQuantity = Asserted(+    quantity,+    .greaterOrEqual(1),+    file: file, +    line: line+  )   +  if validatedQuantity.wrappedValue == 1 {+    // The lack of property-wrapper tranformation is+    // evident here.+    ...+  } }+```++This not only makes writing easy-to-maintain validations easy, but improves debugging for the the API's users as well. Unfortunately, it still lacks the elegant syntax property wrappers offer, making the creation of new functions a demanding task.++### Pass-by-value for reference types +The `@NSCopying` attribute is a tool to emulate value semantics for reference-type properties. The same functionality can now be implemented as a property wrapper, as shown in [SE-0258](https://github.com/apple/swift-evolution/blob/master/proposals/0258-property-wrappers.md#nscopying): -func openEditor(with swiftFile: URL) -> TextEditor {-  TextEditor(document: State(wrappedValue: swiftFile))-  // The wrapped type isn't accepted here; instead we have -  // to use the backing property-wrapper type: 'State'.+```swift+@propertyWrapper+struct Copying<Value: NSCopying> {+  private var _value: Value++  init(wrappedValue value: Value) {+    // Copy the value on initialization.+    self._value = value.copy() as! Value+  }++  var wrappedValue: Value {+    get { return _value }+    set {+      // Copy the value on reassignment.+      _value = newValue.copy() as! Value+    }+  } } ``` -Note also that the argument label does not change when the memberwise initializer uses the backing wrapper type instead of the wrapped-value type.+However, this property wrapper cannot be used on parameters to achieve pass-by-value semantics for reference-type arguments. To achieve pass-by-value semantics, `copy()` must be called manually, which is easy to forget, or the `Copying` type must be used directly in an API, which causes each call-site to manually create an instance of `Copying`. -If the generated memberwise initializer always accepted the backing wrapper type while still allowing the call-site the convenience of automatically initializing the backing wrapper via a wrapped-value type, the mental model for property wrapper initialization would be greatly simplified. Moreover, this would provide more control over the backing-wrapper initialization at the call-site.--### Function parameters with property wrapper type+### Memberwise initialization -Using property-wrapper types for function parameters also results in boilerplate code, both in the function body and at the call-site:+Consider the following property wrapper, inspired by `@Traceable` from [David Piper's blog post](https://medium.com/better-programming/creating-a-history-with-property-wrappers-in-swift-5-1-4c0202060a7f), which tracks the history of a value:  ```swift+struct History<Value> { ... }+ @propertyWrapper-struct Lowercased {+struct Traceable<Value> { -  init(wrappedValue: String) { ... }+  init(wrappedValue value: Value) { ... } +  init(projectedValue: History<Value>) { ... } -  var wrappedValue: String {-    get { ... }-    set { ... }+  var wrappedValue: Value {+    get {+      return history.currentValue+    }+    set {+      history.append(newValue)+    }   }-  ++  var projectedValue: History<Value> { return history }++  private var history: History<Value>+ }+``` +This property wrapper can be initialized with a value to be traced, or with an existing history of a value being traced. Now consider the following model for a simple text editor that supports change tracking: -func postUrl(urlString: Lowercased) {-  guard let url = URL(string: urlString.wrappedValue) else { return }-    //                                 ^~~~~~~~~~~~~-    // We must access 'wrappedValue' manually.-  ...+```swift+struct TextEditor {+  @Traceable var dataSource: String }+```++Currently, property-wrapper attributes on struct properties interact with function parameters through the struct's synthesized memberwise initializer. Because the `@Traceable` property wrapper supports initialization from a wrapped value via `init(wrappedValue:)`, the memberwise initializer for `TextEditor` will take in a `String`. However, the programmer may want to initialize `TextEditor` with a string value that already has a history. Today, this can be achieved with overloads, which can greatly impact compile-time performance, or by exposing the `Traceable` type through the `TextEditor` initializer, which is meant to be implementation detail.++## Proposed solution +We propose to allow application of property wrappers on function and closure parameters, allowing the call-site to pass a wrapped value or a projected value which will be used to automatically initialize the backing property wrapper. -postUrl(urlString: Lowercased(wrappedValue: "mySite.xyz/myUnformattedUsErNAme"))-//                 ^~~~~~~~~~-// We must initialize `Lowercased` manually,-// instead of automatically initializing-// from its wrapped value type.+Using property-wrapper parameters, the above argument validation example can be simplified to:++```swift+func buy(+  @Asserted(.greaterOrEqual(1)) quantity: Int,+  of product: Product,+) {+  if quantity == 1 {+    ...+  }+} ``` -In the above example, the inability to apply property wrappers to function parameters prevents the programmer from removing unnecessary details from the code. The call-site of `postUrl` is forced to initialize an instance of `Lowercased` manually using `init(wrappedValue:)`, even though this initailization is automatic when using `@Lowercased` on a local variable or type property. Further, manually accessing `wrappedValue` in the function body can be distracting when trying to understand the implementation. These limitations are emphasized by the fact that property wrappers were originally sought out to eliminate such boilerplate.+## Detailed design++Property wrappers are essentially sugar wrapping a given declaration with compiler-synthesized code. Retaining this principle, a function can now be called with the wrapped and projected values. Namely, annotating a parameter declaration with a property-wrapper attribute changes the declaration’s type to the backing storage, and prompts the compiler to synthesize the wrapped and projected values. Furthermore, when the function is called the compiler will insert a call to the appropriate property-wrapper initializer. -### Closures accepting property-wrapper types+### Function-body semantics -Consider the following SwiftUI code, which uses [`ForEach`](https://developer.apple.com/documentation/swiftui/foreach) over a collection:+Attaching a property wrapper to a parameter makes that parameter a computed variable local to the function body, and changes the parameter type to the backing wrapper type. The type of the parameter is only observable in compiled code - [unapplied references to functions with property-wrapped parameters](#unapplied-function-references) will not use the backing-wrapper type.++The transformation of function with a property-wrapped parameter will be performed as such:++1. The argument label will remain unchanged. +2. The parameter name will be prefixed with an underscore.+3. The type of the parameter will be the backing property-wrapper type.+4. A local computed property representing the `wrappedValue` of the innermost property wrapper will be synthesized with the same name as the original, unprefixed parameter name. If the innermost `wrappedValue` defines a setter, a setter will be synthesized for the local property if the mutability of the composed setter is `nonmutating`. The mutability computation is specified in the [appendix](#appendix).+5. If the outermost property wrapper defines a `projectedValue` property with a `nonmutating` getter, a local computed property representing the outermost `projectedValue` will be synthesized and named per the original parameter name prefixed with a dollar sign (`$`). If the outermost `projectedValue` defines a setter, a setter for the local computed property will be synthesized if the `projectedValue` setter is `nonmutating`.++Consider the following function with a property-wrapped parameter using the `@Asserted` property wrapper:  ```swift-struct MyView : View {+func insert(@Asserted(.nonEmpty) text: String) { ... }+``` -  // A simple Shopping Item that includes-  // a 'quantity' and a 'name' property.-  @State-  private var shoppingItems: [Item]+The compiler will synthesize computed `text` and `$text` variables in the body of `insert`: -  var body: some View {-    ForEach(0 ..< shoppingItems.count) { index in-      TextField(shoppingItems[index].name, $shoppingItems[index].name)-    }+```swift+func insert(text _text: Asserted<String>) {+  var text: String {+    get { _text.wrappedValue }+  }++  var $text: Result<String, ValidationResult> {+    get { _text.projectedValue }   } +  ... } ``` -Working with `shoppingItems` in the closure body is painful, because the code must manually index into the original wrapped property, rather than working with collection elements directly in the closure. The manual indexing would be alleviated if the closure accepted `Binding`s to collection elements:+### Call-site semantics++When passing an argument to a function with a property-wrapped parameter, the compiler will wrap the argument in a call to the appropriate initializer depending on the argument label. When using the original argument label (or no argument label), the compiler will wrap the argument in a call to `init(wrappedValue:)`. When using the argument label prefixed with `$` (or `$_` in the case of no argument label), the compiler will wrap the argument in a call to `init(projectedValue:)`. ++Consider the `@Traceable` property wrapper that implements both `init(wrappedValue:)` and `init(projectedValue:)`:  ```swift-struct MyView : View {+struct History<Value> { ... } -  // A simple Shopping Item that includes-  // a 'quantity' and a 'name' property.-  @State-  private var shoppingItems: [Item]+@propertyWrapper+struct Traceable<Value> { -  var body: some View {-    ForEach($shoppingItems) { itemBinding in-      TextField(itemBinding.wrappedValue.name, itemBinding.name)-    }-  }+  init(wrappedValue value: Value)++  init(projectedValue: History<Value>)++  var wrappedValue: Value++  var projectedValue: History<Value>  } ``` -However, now we observe the same boilerplate code in the closure body because the property-wrapper syntax cannot be used with the closure parameter.+A function with an `@Traceable` parameter can be called with either a wrapped value or a projected value: -## Proposed solution+```swift+func log<Value>(@Traceable value: Value) { ... } -We propose to allow application of property wrappers on function and closure parameters.+let history: History<Int> = ...+log(value: 10)+log($value: history)+``` -Using property-wrapper parameters, the above `postUrl` example becomes:+The compiler will inject a call to the appropriate property-wrapper initializer into each call to `log` based on the argument label, so the above code is transformed to:  ```swift-func postUrl(@Lowercased urlString: String) {-  guard let url = URL(string: urlString) else { return }-  ...-}--postUrl(urlString: "mySite.xyz/myUnformattedUsErNAme")+log(value: Traceable(wrappedValue: 10))+log(value: Traceable(projectedValue: history)) ``` -In the above SwiftUI example, if collection elements could be accessed via `Binding`s in the `ForEach` closure, property-wrapper parameters could be used to enable property-wrapper syntax in the closure body:+Wrapped parameters with no argument label can still be passed a projection using the syntax `$_:`, as shown in the following example:  ```swift-struct MyView: View {+func log<Value>(@Traceable _ value: Value) { ... }++let history: History<Int> = ...+log(10)+log(_: 10)+log($_: history)+``` -  @State-  private var shoppingItems: [Item]+For composed property wrappers, initialization of the backing wrapper via wrapped value will contain a call to `init(wrappedValue:)` for each property-wrapper attribute in the composition chain. However, initialization via projected value will only contain one call to `init(projectedValue:)` for the outermost wrapper attribute, because property wrapper projections are not composed. For example:  -  var body: some View {-    ForEach($shoppingItems) { (@Binding item) in-      TextField(item.name, $item.name)-    }-  }+```swift+func log(@Traceable @Traceable text: String) { ... } -}+let history: History<Traceable<String>> = ...+log(text: "Hello!")+log($text: history) ``` -## Detailed design+The above calls to `log` are transformed to: -Property wrappers are essentially sugar wrapping a given property with compiler-synthesized code. This proposal retains this principle, employing the following transformation.+```swift+log(text: Traceable(wrappedValue: Traceable(wrappedValue: "Hello!"))+log(text: Traceable(projectedValue: history))+``` -### Function body transformation+This transformation at the call-site only applies when calling the function directly using the declaration name. The semantics of closures and unapplied function references are specified [in a later section](#semantics-of-function-expressions). -The transformation of function with a property-wrapper parameter will be performed as such:+#### Passing a projected value argument -1. For regular functions, the argument label will remain unchanged. -2. The parameter name will be prefixed with an underscore.-3. The type of the parameter will be the backing property-wrapper type.-4. A local computed property representing the `wrappedValue` of the innermost property wrapper will be synthesized with the same name as the original, unprefixed parameter name. If the innermost `wrappedValue` defines a setter, a setter will be synthesized for the local property if the mutability of the composed setter is `nonmutating`. The mutability computation is specified below.-5. If the outermost property wrapper defines a `projectedValue` property, a local computed property representing the outermost `projectedValue` will be synthesized and named per the original parameter name prefixed with a dollar sign (`$`). If the outermost `projectedValue` defines a setter, a setter for the local computed property will be synthesized if the `projectedValue` setter is `nonmutating`, or if the outermost wrapper is a reference type.+Property wrappers can opt into passing a projected-value argument to a property-wrapped parameter. -#### Mutability of composed `wrappedValue` accessors+Though property-wrapper projections can be utilized to expose arbitrary API through the synthesized `$` property, projections are typically used to either publicly expose the backing property wrapper directly, or to provide a public representation of the backing wrapper that's suitable for use outside of the declaration that owns the wrapper storage. In such cases, supporting property-wrapper initialization from a projected-value is very useful, especially if the wrapper does not support `init(wrappedValue:)`. To support passing a property-wrapper projection to a function with a wrapped parameter, property wrappers can implement `init(projectedValue:)`. -The computation for mutability of a wrapped parameter's composed `wrappedValue` accessors will be the same as it is today for wrapped properties. The computation starts with the mutability of the outermost wrapper's `wrappedValue` accessor, and then iterates over the chain of composed property wrappers, "composing" the mutability of each `wrappedValue` accessor along the way using the following rules, which are the same for getters and setters:+Presence of an `init(projectedValue:)` that meets the following requirements enables passing a projected value via the `$` calling syntax: -* If the next `wrappedValue` accessor is `nonmutating`, then the mutability of the composed accessor is the same as the previous composed getter. If the wrapper is a reference type, the accessor is considered `nonmutating`.-* If the next `wrappedValue` accessor is `mutating`, then the composed accessor is `mutating` if the previous composed getter _or_ setter is `mutating`, since both are needed to perform a writeback cycle.+- The first parameter of this initializer must be labeled `projectedValue` and have the same type as the `var projectedValue` property.

If I understand correctly, declaring a projectedValue property is not mandatory; should we perhaps state this explicitly?

We should probably add a rationale for this behavior, as well.

filip-sakel

comment created time in 4 hours

issue openedswift-server/swift-service-lifecycle

Swift Metrics is included in the Package but is never used

Is there a plan to use it at some point?

created time in 4 hours

PR opened grpc/grpc-swift

Fix some bugs with new handlers

Motivation:

Manually wiring up the new handlers to run the rest of the test suite highlighted a few rough edges.

Modifications:

  • Make sure compression is correctly set: it must be enabled on the server, in the call context, and - if applicable - on the individaul message. Add tests for this.
  • Call the error delegate in the right place.
  • Add a 'protocol violation' error.

Result:

Fewer bugs.

+391 -112

0 comment

10 changed files

pr created time in 4 hours

PR opened grpc/grpc-swift

Reviewers
Support new handlers in the server codec + state machine semver-patch •

Motivation:

We have new ways of handling RPCs on the server, the server codec and state machine should use them!

Modifications:

  • In the state machine: try to handle an RPC using the new API, falling back to the old way
  • In the codec: store a mode, i.e. how we're handling the RPC.
  • Flushing has become the responsibility of the server codec (as opposed to the RPC-specific channel handler): now we only flush at the end of 'channelReadComplete' (if a flush is pending), or on calls to 'flush(context:)' if we aren't currently reading.

Result:

The server supports the new RPC handlers.

+232 -87

0 comment

3 changed files

pr created time in 5 hours

issue closedgrpc/grpc-swift

Project with GRPC dependencies not build from commandline

SPMs for SwiftNIO builds in wrong order

Steps to reproduce:

  1. Create new project
  2. File -> Swift packages -> add package dependency Use https://github.com/grpc/grpc-swift.git exact Swift 1.0.0-alpha.21
  3. build in XCode. Build succeeded
  4. close xcode
  5. run terminal
  6. Goto folder with project cd ~/projects/<use your path>/
  7. Run xcodebuild

Actual result: Library/Developer/Xcode/DerivedData/MultiScreen-gstsxmaaiuzazmcmkxnwlwsczybn/SourcePackages/checkouts/swift-nio-transport-services/Sources/NIOTransportServices/NIOFilterEmptyWritesHandler.swift:15:8: error: no such module 'NIO' import NIO

BUILD FAILED **

xcode 12.3

closed time in 8 hours

ibaho

push eventgrpc/grpc-swift

George Barnett

commit sha 3d8d32359467c618de5a4a568797f129b799fa9a

Simplify some of the interaction between HTTP2 to GRPC state machine and codec (#1100) Motivation: The HTTP2ToRawGRPCStateMachine returns a somewhat generic 'Action' which the called is meant to act on. This pattern was used wholesale for every interaction with the statemachine. This is a little silly: in some cases the cases any action can be specified just fine with a `Bool`, in others a `Result` is fine. The other downside to this approach is that it makes it harder to see at the callsite what could happen as a result of interacting with the state machine. Modifications: - Specify an action to take for each different interaction with the state machine. - Update tests. Result: A handful of smallish reductions in instructions: - unary_10k_small_requests: -0.5% - embedded_server_unary_10k_small_requests: -2.6% - embedded_server_client_streaming_1_rpc_10k_small_requests: -4.0% - embedded_server_client_streaming_10k_rpcs_1_small_requests: -2.6% - embedded_server_server_streaming_1_rpc_10k_small_responses: -1.7% - embedded_server_server_streaming_10k_rpcs_1_small_response: -2.6% - embedded_server_bidi_1_rpc_10k_small_requests: -3.1% - embedded_server_bidi_10k_rpcs_1_small_request: -2.4%

view details

push time in 11 hours

PR merged grpc/grpc-swift

Simplify some of the interaction between HTTP2 to GRPC state machine … semver-patch •

…and codec

Motivation:

The HTTP2ToRawGRPCStateMachine returns a somewhat generic 'Action' which the called is meant to act on. This pattern was used wholesale for every interaction with the statemachine. This is a little silly: in some cases the cases any action can be specified just fine with a Bool, in others a Result is fine. The other downside to this approach is that it makes it harder to see at the callsite what could happen as a result of interacting with the state machine.

Modifications:

  • Specify an action to take for each different interaction with the state machine.
  • Update tests.

Result:

A handful of reductions in instructions in benchmarks:

  • unary_10k_small_requests: -0.5%
  • embedded_server_unary_10k_small_requests: -2.6%
  • embedded_server_client_streaming_1_rpc_10k_small_requests: -4.0%
  • embedded_server_client_streaming_10k_rpcs_1_small_requests: -2.6%
  • embedded_server_server_streaming_1_rpc_10k_small_responses: -1.7%
  • embedded_server_server_streaming_10k_rpcs_1_small_response: -2.6%
  • embedded_server_bidi_1_rpc_10k_small_requests: -3.1%
  • embedded_server_bidi_10k_rpcs_1_small_request: -2.4%
+337 -431

0 comment

4 changed files

glbrntt

pr closed time in 11 hours

Pull request review commentapple/swift-evolution

[Proposal Revision] Extend property wrappers to functions and closure parameters.

 generic(arg: [1, 2, 3]) // calls the constrained init(wrappedValue:)                         // because the argument conforms to Collection. ``` -### Closures and unapplied function references+### Semantics of function expressions -By default, closures and unapplied references to functions that accept property-wrapped parameters use the wrapped-value type in the parameter list, and the compiler will generate a thunk to initialize the backing wrapper and call the function.+#### Unapplied function references -Consider the following function which uses the [`@Clamping`](https://github.com/apple/swift-evolution/blob/main/proposals/0258-property-wrappers.md#clamping-a-value-within-bounds) property wrapper:+By default, unapplied references to functions that accept property-wrapped parameters use the wrapped-value type in the parameter list, and the compiler will generate a thunk to initialize the backing wrapper and call the function.++Consider the `log` function from above, which uses the `@Traceable` property wrapper:  ```swift-func reportProgress(@Clamping(min: 0, max: 100) percent: Int) { ... }+func log<Value>(@Traceable value: Value) { ... } ``` -The type of `reportProgress` is `(Int) -> Void`. These semantics can be observed when working with an unapplied reference to `reportProgress`:+The type of `log` is `(Value) -> Void`. These semantics can be observed when working with an unapplied reference to `log`:  ```swift-let fnRef: (Int) -> Void = reportProgress+let fnRef: (Int) -> Void = log fnRef(10)++let fnRefWithLabel: (Int) -> Void = log(value:)+fnRefWithLabel(10) ``` -The compiler will generate a thunk when referencing `reportProgress` to take in the wrapped-value type and initialize the backing property wrapper:+The compiler will generate a thunk when referencing `log` to take in the wrapped-value type and initialize the backing property wrapper. Both references to `log` in the above example are transformed to:  ```swift-let fnRef: (Int) -> Void =  { reportProgress(percent: Clamping(wrappedValue: $0, min: 0, max: 100) }+{ log(value: Traceable(wrappedValue: $0) } ``` -The type of a closure or unapplied function reference can be changed to instead take in the projected-value type using `$` in front of the parameter name in a closure or in front of the argument label in a function reference. Consider the following `UnsafeMutableReference` property wrapper that projects an `UnsafeMutablePointer` and implements `init(projectedValue:)`:+The type of an unapplied function reference can be changed to instead take in the projected-value type using `$` in front of the argument label. Since `Traceable` implements `init(projectedValue:)`, the `log` function can be referenced in a way that takes in `History` by using `$` in front of `value`:  ```swift-@propertyWrapper-struct UnsafeMutableReference<Value> {+let history: History<Int> = ...+let fnRef: (History<Int>) -> Void = log($value:)+fnRef(history)+``` -  init(projectedValue: UnsafeMutablePointer<Value>) { ... }+If the property-wrapped parameter in `log` omits an argument label, the function can still be referenced to take in the projected-value type using `$_`: -}+```swift+func log<Value>(@Traceable _ value: Value) { ... }++let history: History<Int> = ...+let fnRef: (History<Int>) -> Void = log($_:)

Name suggestions: functionReference, logReference, reference. Having 'fnRef' seems a bit unswifty.

filip-sakel

comment created time in a day

push eventapple/swift-evolution

Max Desiatov

commit sha ea73f60935b3d0f0730920bcb386225fa6b6ec80

Enable Swift syntax highlighting in SE-0300 (#1252)

view details

push time in a day

pull request commentapple/swift-evolution

Enable Swift syntax highlighting in SE-0300

thx!

MaxDesiatov

comment created time in a day

push eventapple/swift-evolution

Becca Royal-Gordon

commit sha bdfc22a691cee0f37f340ea0f8955ae691fd8bac

Correct contributor’s name

view details

Becca (née Brent) Royal-Gordon

commit sha b2c3fc5320a215fd7e0587e0069cb403a91218b8

Merge pull request #1253 from beccadax/my-name-is-neo Correct contributor’s name

view details

push time in 2 days

PR merged apple/swift-evolution

Correct contributor’s name

See also apple/swift#35460.

+27 -27

0 comment

20 changed files

beccadax

pr closed time in 2 days

PR opened apple/swift-evolution

Correct contributor’s name

See also apple/swift#35460.

+27 -27

0 comment

20 changed files

pr created time in 2 days

issue commentapple/swift-system

Increased API Coverage

Thanks @miles. For reference, here's where I used the package. It's a great example of where the API's coverage is quite low.

Really glad to see this package coming along though!

milseman

comment created time in 2 days

Pull request review commentapple/swift-system

[Draft]: FilePath syntactic operations

+/*+ This source file is part of the Swift System open source project++ Copyright (c) 2020 Apple Inc. and the Swift System project authors+ Licensed under Apache License v2.0 with Runtime Library Exception++ See https://swift.org/LICENSE.txt for license information+*/++// @available(macOS 10.16, iOS 14.0, watchOS 7.0, tvOS 14.0, *)+extension FilePath {+  /// Creates a file path by copying bytes from a null-terminated platform string.+  ///+  /// - Parameter platformString: A pointer to a null-terminated platform string.+  public init(platformString: UnsafePointer<PlatformChar>) {+    self.init(SystemString(platformString: platformString))+  }++  /// Calls the given closure with a pointer to the contents of the file path,+  /// represented as a null-terminated platform string.+  ///+  /// - Parameter body: A closure with a pointer parameter+  ///   that points to a null-terminated platform string.+  ///   If `body` has a return value,+  ///   that value is also used as the return value for this method.+  /// - Returns: The return value, if any, of the `body` closure parameter.+  ///+  /// The pointer passed as an argument to `body` is valid+  /// only during the execution of this method.+  /// Don't try to store the pointer for later use.+  public func withPlatformString<Result>(+    _ body: (UnsafePointer<PlatformChar>) throws -> Result+  ) rethrows -> Result {+    try storage.withPlatformString(body)+  }+}++extension FilePath.Component {+  /// Creates a file path component by copying bytes from a null-terminated platform string.+  ///+  /// - Parameter string: A pointer to a null-terminated platform string.+  public init(platformString: UnsafePointer<PlatformChar>) {+    self.init(SystemString(platformString: platformString))+  }++  /// Calls the given closure with a pointer to the contents of the file path component,+  /// represented as a null-terminated platform string.+  ///+  /// If this is not the last component of a path, an allocation will occur in order to+  /// add the null terminator+  ///+  /// - Parameter body: A closure with a pointer parameter+  ///   that points to a null-terminated platform string.+  ///   If `body` has a return value,+  ///   that value is also used as the return value for this method.+  /// - Returns: The return value, if any, of the `body` closure parameter.+  ///+  /// The pointer passed as an argument to `body` is valid+  /// only during the execution of this method.+  /// Don't try to store the pointer for later use.+  public func withPlatformString<Result>(+    _ body: (UnsafePointer<PlatformChar>) throws -> Result+  ) rethrows -> Result {+    try slice.withPlatformString(body)+  }+}++++// @available(macOS 10.16, iOS 14.0, watchOS 7.0, tvOS 14.0, *)+extension FilePath: ExpressibleByStringLiteral {+  /// Creates a file path from a string literal.+  ///+  /// - Parameter stringLiteral: A string literal+  ///   whose Unicode encoded contents to use as the contents of the path.+  public init(stringLiteral: String) {+    self.init(stringLiteral)+  }++  /// Creates a file path from a string.+  ///+  /// - Parameter string: A string+  ///   whose Unicode encoded contents to use as the contents of the path.+  public init(_ string: String) {+    self.init(SystemString(string))+  }+}++// @available(macOS 10.16, iOS 14.0, watchOS 7.0, tvOS 14.0, *)+extension String {+  /// Creates a string by interpreting the file path's content as UTF-8 on Unix+  /// and UTF-16 on Windows.+  ///+  /// - Parameter path: The file path to be interpreted as `PlatformUnicodeEncoding`.+  ///+  /// If the content of the file path isn't a well-formed Unicode string,+  /// this initializer replaces invalid bytes them with U+FFFD.+  /// This means that, depending on the semantics of the specific file system,+  /// conversion to a string and back to a path+  /// might result in a value that's different from the original path.+  public init(decoding path: FilePath) {+    self = path.withPlatformString { String(platformString: $0) }+  }++  /// Creates a string from a file path, validating its contents as UTF-8 on Unix+  /// and UTF-16 on Windows.+  ///+  /// - Parameter path: The file path to be interpreted as `PlatformUnicodeEncoding`.+  ///+  /// If the contents of the file path isn't a well-formed Unicode string,+  /// this initializer returns `nil`.+  public init?(validating path: FilePath) {+    guard let str = path.withPlatformString(+      String.init(validatingPlatformString:)+    ) else {+      return nil+    }+    self = str+  }+}+++// @available(macOS 10.16, iOS 14.0, watchOS 7.0, tvOS 14.0, *)+extension FilePath: CustomStringConvertible, CustomDebugStringConvertible {+  /// A textual representation of the file path.+  ///+  /// If the content of the path isn't a well-formed Unicode string,+  /// this replaces invalid bytes them with U+FFFD. See `String.init(decoding:)`+  @inline(never)+  public var description: String { String(decoding: self) }++  /// A textual representation of the file path, suitable for debugging.+  ///+  /// If the content of the path isn't a well-formed Unicode string,+  /// this replaces invalid bytes them with U+FFFD. See `String.init(decoding:)`+  public var debugDescription: String { description.debugDescription }+}++// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)+extension String {+  /// Creates a string by interpreting the path component's content as UTF-8 on Unix+  /// and UTF-16 on Windows.+  ///+  /// - Parameter path: The path component to be interpreted as `PlatformUnicodeEncoding`.

The initializer methods in this extension appear to be documented incorrectly. Please correct me if I am wrong, but I believe IDEs would expect - Parameter path: to describe a parameter that is not named in any of these signatures. Should these documentation comments instead read - Parameter component?

Also, below is another instance of "invalid bytes them".

milseman

comment created time in 3 days

push eventapple/swift-evolution

Joe Groff

commit sha 5f79481244329ec2860951c0c49c101aef5069e7

Introduce a dedicated proposal for `with*Continuation` (#1244) * Introduce a dedicated proposal for `with*Continuation` * Updates in response to feedback - Trap on multiple resumes, rather than merely logging - Add discussion of alternatives considered, such as trapping vs logging tradeoffs, and lack of additional handle API * Add some more interesting examples from the pitch discussion * Add an example of a callback-based API respecting its parent task's cancellation state. Provided by @ktoso * Assign number, review manager Co-authored-by: Ben Cohen <airspeedswift@users.noreply.github.com>

view details

push time in 3 days

Pull request review commentapple/swift-evolution

[Proposal Revision] Extend property wrappers to functions and closure parameters.

 Property Wrappers were [introduced in Swift 5.1](https://github.com/apple/swift-  Property wrappers have undoubtably been very successful. Applying a property wrapper to a property is enabled by an incredibly lightweight and expressive syntax. For instance, frameworks such as [SwiftUI](https://developer.apple.com/documentation/swiftui/) and [Combine](https://developer.apple.com/documentation/combine) introduce property wrappers such as [`State`](https://developer.apple.com/documentation/swiftui/state), [`Binding`](https://developer.apple.com/documentation/swiftui/binding) and [`Published`](https://developer.apple.com/documentation/combine/published) to expose elaborate behavior through a succinct interface, helping craft expressive yet simple APIs. However, property wrappers are only applicable to local variables and type properties, shattering the illusion that they helped realize in the first place when working with parameters. -### Memberwise initialization+Property wrappers attached to parameters have a wide variety of use cases. We present a few examples here. -Currently, property-wrapper attributes on struct properties interact with function parameters through the struct's synthesized memberwise initializer. However, property-wrapper attributes are _not_ supported on function parameters. This leads to complicated and nuanced rules for which type, between the wrapped-value type and the backing property-wrapper type, the memberwise initializer accepts.+### Argument validation -The compiler will choose the wrapped-value type to offer a convenience to the call-site when the property wrapper has an initializer of the form `init(wrappedValue:)` accepting the wrapped-value type, as seen here:+Both library developers and language users often need to assert their assumptions, for which `precondition(_:_:)` is often used:  ```swift-import SwiftUI---struct TextEditor {--  @State var document: Optional<URL>-  +enum Product {+  case plainSandwich +  case grilledCheeseSandwich +  case avocadoToast } --func openEditor(with swiftFile: URL) -> TextEditor {-  TextEditor(document: swiftFile) -  // The wrapped type is accepted here.+func buy(quantity: Int, of product: Product) {+  precondition(quanity >= 1, "Invalid product quanity.")+  +  if quantity == 1 {+    ...+  } } ``` -However, this can take flexibility away from the call-site if the property wrapper has other `init` overloads, because the call-site _cannot_ choose a different initializer. Further, if the property wrapper is explicitly initialized via `init()`, then the memberwise initializer will choose the backing-wrapper type, even if the wrapper supports `init(wrappedValue:)`. This results in unnecessary boilerplate at call-sites that _do_ want to use `init(wrappedValue:)`:+The above code is quite clear; it has, though, the obvious drawback that changing the the condition to be asserted or its error message requires significant effort as a precondition statement is individually written for each function and manually documented.++Furthermore, supposing the above is library code, we may want to test for our precondition while offering an easy-to-debug way. So, using `Validation` from [`ValidatedPropertyKit`](https://github.com/SvenTiigi/ValidatedPropertyKit) we can write:  ```swift-import SwiftUI+@propertyWrapper

Oh I see. I was confused because the function below this used Validated so I thought it was just a mistake, sorry! I do think it would be fine to use (a variation of) the Validated property wrapper from the package, but please feel free to change the name to whatever you think is best

filip-sakel

comment created time in 3 days

push eventgrpc/grpc-swift

George Barnett

commit sha 7606b999c745a65ef69d5ea412f0030da4f47825

Add a bidirectional streaming server handler. (#1098) Motivation: Following from #1093, #1095 and #1097; we need a bidirectional streaming server handler. Modifications: - Add a bidirectional streaming server handler and tests. Result: We'll be able to do bidirectional streaming RPCs with new codegen.

view details

push time in 3 days

PR merged grpc/grpc-swift

Add a bidirectional streaming server handler. semver-minor ↑

Motivation:

Following from #1093, #1095 and #1097; we need a bidirectional streaming server handler.

Modifications:

  • Add a bidirectional streaming server handler and tests.

Result:

We'll be able to do bidirectional streaming RPCs with new codegen.

+593 -0

0 comment

2 changed files

glbrntt

pr closed time in 3 days

more