Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal to change the assignment operator in ValueSet #17

Open
guidomb opened this issue Jan 27, 2018 · 5 comments
Open

Proposal to change the assignment operator in ValueSet #17

guidomb opened this issue Jan 27, 2018 · 5 comments
Labels

Comments

@guidomb
Copy link

guidomb commented Jan 27, 2018

As I mentioned @mdiep before, I think that using the == operator for assignment in ValueSets is confusing. I think people (or at least in my case) would be confused to see the equality operator being used in such way. I think the == is one of those operator that you see in almost every programming language so people would probably assume that a comparison is being performed while skimming through the code.

The first time I saw the following example I had to pay special attention to how the Insert value was constructed.

struct Task {
    public let id: UUID
    public let createdAt: Date
    public var text: String
    public var url: URL?
    
    public static func newTask(text: String, url: URL? = nil) -> Insert<Task> {
        return Insert([
            \Task.id == .uuid(),
            \Task.createdAt == .now,
            \Task.text == text,
            \Task.url == url,
        ])
    }
}

After giving it a second look I assumed that == was not being used as the equality operator and then had to read PersistDB's source code to understand how ValueSet works.

I think that using <~ or <- or <-- or := would be better and at least won't be confused with the equality operator at first glance. If I had to pick one I would choose := because it is used in other programming languages (like Go or Pascal) as the assignment operator.

@mdiep
Copy link
Collaborator

mdiep commented Jan 28, 2018

:= won't work because it's not a valid Swift operator. 😞

Custom operators can begin with one of the ASCII characters /, =, -, +, !, *, %, <, >, &, |, ^, ?, or ~, or one of the Unicode characters defined in the grammar below (which include characters from the Mathematical Operators, Miscellaneous Symbols, and Dingbats Unicode blocks, among others). After the first character, combining Unicode characters are also allowed.

I considered using <~ since it's also used in ReactiveSwift and some other things. Unfortunately, using it here would mean that you'd have to import ReactiveSwift to create an Insert or Update, and that didn't seem right.

My thinking was that == makes sense because if you take step back you are declaring an equality, not making an imperative assignment. But I do see how that could be confusing. The biggest obstacle is finding something else that makes sense, is allowed by Swift, and isn't widely used (to avoid conflicts).

Maybe let's leave this open to see if other people find == confusing here? (And to see if anyone has a great suggestion.)

@sharplet
Copy link
Contributor

Would it be possible to use dictionary literal syntax to construct this? Syntactically it makes sense:

        return Insert([
            \Task.id: .uuid(),
            \Task.createdAt: .now,
            \Task.text: text,
            \Task.url: url,
        ])

There's a built in type called DictionaryLiteral that essentially turns the literal syntax into a collection of key-value pairs, preserving their declaration order. It's also possible to use ExpressibleByDictionaryLiteral with a custom type.

@mdiep
Copy link
Collaborator

mdiep commented Jan 28, 2018

Unfortunately, this can’t be modeled as a dictionary. Each of the pairs shares a type for the value, which is erased as it enters the array but guarantees that the left- and right-hand side of each assignment is the same.

\Task.id == .uuid() // Assignment<Task>
\Task.id // KeyPath<Task, UUID>
.uuid() // Expression<Task, UUID>
== // (KeyPath<Model, Value>, Expression<Model, Value>) -> Assignment<Model>

@guidomb
Copy link
Author

guidomb commented Jan 28, 2018

@mdiep Why using <~ would require importing ReactiveSwift? Can't you define an overload for <~ in the PersistDB module space? Maybe for ReactiveSwift users using the property binding operator could be confusing but I don't think is as "standardized" as ==.

Maybe <- or <-- could be consider.

Maybe let's leave this open to see if other people find == confusing here? (And to see if anyone has a great suggestion.)

Sounds good. This is the sort of thing were there is not "right answer".

@mdiep
Copy link
Collaborator

mdiep commented Jan 29, 2018

Why using <~ would require importing ReactiveSwift? Can't you define an overload for <~ in the PersistDB module space? Maybe for ReactiveSwift users using the property binding operator could be confusing but I don't think is as "standardized" as ==.

I guess you can! I didn't think you could redeclare the operator, but it doesn't look like that actually causes issues. 🤔

I think I'd still like to sit on this for a bit. 🤔

@mdiep mdiep added the proposal label Jan 29, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants