[swift-evolution] "with" operator a la O'Caml?

Derrick Ho wh1pch81n at gmail.com
Mon Dec 19 15:47:16 CST 2016


That is correct Andy. Let-constant can not be assigned a new value after it
gets its initial value.

It is unclear why you are against turning your properties into var's.
Because you are using structs, all properties are copied by value.

struct Person {
  var name: String
}

let andy = Person(name: "Andy")
var brandon = andy; brandon.name = "Brandon"

andy.name // "Andy"
brandon.name // "Brandon"

I believe this accomplishes the same thing you wanted in with(name:)

On Mon, Dec 19, 2016 at 1:26 PM Andy Chou via swift-evolution <
swift-evolution at swift.org> wrote:

Thanks Erica, I wasn't aware of that Swift evolution proposal. If I'm
reading it right, this wouldn't work with structs with let-variables...?
Here's what I get with this example:

struct Person {
    let name: String
    let address: String
}

@discardableResult
public func with<T>(_ item: T, update:
(inout T) throws -> Void) rethrows -> T {
    var this = item
    try update(&this)
    return this
}

let john = Person(name: "John", address: "1 battery st")
let jane: Person = with(john) { $0.name = "Jane" }     // Test.swift:24:41:
Cannot assign to property: 'name' is a 'let' constant

Andy


On Dec 19, 2016, at 11:44 AM, Erica Sadun <erica at ericasadun.com> wrote:

https://github.com/apple/swift-evolution/pull/346

Be aware that there's a bug that's being worked on:

https://bugs.swift.org/browse/SR-2773

-- E


On Dec 19, 2016, at 12:40 PM, Andy Chou via swift-evolution <
swift-evolution at swift.org> wrote:

Of course. Thanks for pointing out the obvious solution. This preserves the
immutability of the struct and doesn't require O(n^2) code for structs with
large numbers of fields.

I was thinking of a generic solution - perhaps something like a synthetic
initializer that does what your solution does. But that may be overkill
given how relatively easy it is to do this per struct...

On the other hand a generic solution would encourage using immutable
structs. I wasted too much time trying to solve this, I suspect others
would just give up and use var, or even classes.

Andy

On Dec 19, 2016, at 10:43 AM, Nick Keets <nick.keets at gmail.com> wrote:











You are probably asking for a generic solution, but for a specific struct
you can implement it like this:




extension Person {
    func with(name: String? = nil, address: String? = nil, phone: String? =
nil) -> Person {
        let name = name ?? self.name
        let address = address ?? self.address
        let phone = phone ?? self.phone
        return Person(name: name, address: address, phone: phone)
    }
}












On 19 Dec 2016, 20:28 +0200, Andy Chou via swift-evolution <
swift-evolution at swift.org>, wrote:


I like that structs are value types in Swift, this encourages the use of
immutable data. O'Caml has an operator "with" that allows for copying an
existing struct with a change to one field. I looked at Lenses for this
functionality and it seems like a lot to digest for something so simple. I
also tried to implement this using a constructor, or a function, and it was
not obvious how to do so without a lot of code duplication.





What's I'm looking for is something like this (not necessarily with this
syntax):





struct Person {


let name: String


let address: String


let phone: String


}





func f() {


let andy = Person(name: "Andy", address: "1 Battery St., San Francisco,
CA", phone: "1234567")


let chris = andy.with(name: "Chris")


let dave = andy.with(address: "50 Townsend St., San Francisco, CA")


}





I tried to implement a "with" function like this but default arguments
cannot reference properties of self. Same problem trying to do this in a
constructor.





Obviously it's possible to create an entirely new Person specifying the
values from an existing Person, but this is very tedious with structures
with many properties.





Anyone taken a look at this before? Any suggestions?





Andy





_______________________________________________


swift-evolution mailing list


swift-evolution at swift.org


https://lists.swift.org/mailman/listinfo/swift-evolution









_______________________________________________
swift-evolution mailing list
swift-evolution at swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution



_______________________________________________


swift-evolution mailing list


swift-evolution at swift.org


https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161219/77fa9594/attachment.html>


More information about the swift-evolution mailing list