I'd like to think about at least renaming, or maybe even removing, the <| family of operators in Argo. I think this falls in line with the goals for the (theoretical) next release of Argo, where we're going to be renaming large parts of the lib in order to remove ambiguity or clarify library intent (see #474 and #473). There are a couple of reasons for renaming these operators:
- When we first designed Argo, we were unaware of the prior art of using
<| for right-to-left function application in languages like F#. Since becoming aware of this, I've seen |> used more and more for left-to-right function application, and the fact that our operator conflicts with this existing expectation bothers me, and seems like it could lead to confusion.
- Using an operator for extracting values from
JSON instances can to some fairly gnarly code that's really hard to read. Many times, this is due to ambiguous precedence between all of the different operators needed to fully implement a non-trivial decoder.
- The
<| is incredibly specialized, and only really works with the shape JSON -> String -> Decoded<T>. This means its use is limited, and could probably be replaced by a method on JSON itself.
I'd propose making the drastic change of removing the <| family of operators in the next release of Argo in favor of a named method (JSON.extract). For the sake of discussion, here's a sample of the before/after for one of our decode methods in our test suite:
// before
extension User: Argo.Decodable {
static func decode(_ json: JSON) -> Decoded<User> {
return curry(self.init)
<^> json <| "id"
<*> (json <| ["userinfo", "name"] <|> json <| "name")
<*> json <|? "email"
}
}
// after
extension User: Argo.Decodable {
static func decode(_ json: JSON) -> Decoded<User> {
return curry(self.init)
<^> json.extract("id")
<*> json.extract(["userinfo", "name"]) <|> json.extract("name")
<*> json.extractOpt("email")
}
}
The optional method name is an interesting problem to need to solve, I'm not confident that extractOpt is the right choice there. I'd love to do extract? but that's not valid swift. Also, of note: this will be made simpler by the fact that with Swift 4.1 (which we should target for these changes) we'll be able to remove the collection operators (<||) from the lib anyway.
I'd like to think about at least renaming, or maybe even removing, the
<|family of operators in Argo. I think this falls in line with the goals for the (theoretical) next release of Argo, where we're going to be renaming large parts of the lib in order to remove ambiguity or clarify library intent (see #474 and #473). There are a couple of reasons for renaming these operators:<|for right-to-left function application in languages like F#. Since becoming aware of this, I've seen|>used more and more for left-to-right function application, and the fact that our operator conflicts with this existing expectation bothers me, and seems like it could lead to confusion.JSONinstances can to some fairly gnarly code that's really hard to read. Many times, this is due to ambiguous precedence between all of the different operators needed to fully implement a non-trivial decoder.<|is incredibly specialized, and only really works with the shapeJSON -> String -> Decoded<T>. This means its use is limited, and could probably be replaced by a method onJSONitself.I'd propose making the drastic change of removing the
<|family of operators in the next release of Argo in favor of a named method (JSON.extract). For the sake of discussion, here's a sample of the before/after for one of our decode methods in our test suite:The optional method name is an interesting problem to need to solve, I'm not confident that
extractOptis the right choice there. I'd love to doextract?but that's not valid swift. Also, of note: this will be made simpler by the fact that with Swift 4.1 (which we should target for these changes) we'll be able to remove the collection operators (<||) from the lib anyway.