Re:Code Smells: Iteration
by chriswarbo on Thursday August 24, 2017 @07:41AM
(#15089240)
Regarding things like serialising/deserialising, I don't think there's much issue 'philosophically': in the case of Lisp's `read`/`write`, we can spot the ambiguity and deal with it by writing separate functions, for example:
- `serialise`/`deserialise` to produce/consume machine-readable data; must be mutually inverse (which rules out your example of functions).
- `pretty-print` for human consumption; has no inverse.
As a MVP, these could just be wrappers around `read` and `write` (macros would prevent any runtime overhead); the names convey the intended meaning. Later on we could start enforcing some checks, but since Lisp is dynamically typed, we'd have to do runtime tag-checking (e.g. "if type of 'X' is 'function', throw an error"). A static type system/checker would be better.
More generally, each application should be responsible for parsing its input into a domain-specific model, with machine-checked types. A pair of communicating applications may choose to delegate that responsibility to some common library, but they should not assume that their input can be trusted since it's 'coming from that other system'; e.g. they shouldn't pass around a `String` of input as if it were a domain object, and mangle it by pull out particular characters, concatenating things, etc. That `String` should be parsed into its components ASAP, and those should be passed around.
You're right that "apps hungarian" is another possible approach: slightly better than just documentation, but still not manchine-checked. I think the history of apps hungarian degenerating into systems hungarian is another example of this type/representation conflation.
- `serialise`/`deserialise` to produce/consume machine-readable data; must be mutually inverse (which rules out your example of functions).
- `pretty-print` for human consumption; has no inverse.
As a MVP, these could just be wrappers around `read` and `write` (macros would prevent any runtime overhead); the names convey the intended meaning. Later on we could start enforcing some checks, but since Lisp is dynamically typed, we'd have to do runtime tag-checking (e.g. "if type of 'X' is 'function', throw an error"). A static type system/checker would be better.
More generally, each application should be responsible for parsing its input into a domain-specific model, with machine-checked types. A pair of communicating applications may choose to delegate that responsibility to some common library, but they should not assume that their input can be trusted since it's 'coming from that other system'; e.g. they shouldn't pass around a `String` of input as if it were a domain object, and mangle it by pull out particular characters, concatenating things, etc. That `String` should be parsed into its components ASAP, and those should be passed around.
You're right that "apps hungarian" is another possible approach: slightly better than just documentation, but still not manchine-checked. I think the history of apps hungarian degenerating into systems hungarian is another example of this type/representation conflation.