Re: Idle musings on doing E over again
Kevin Reid <kpreid-M/[email protected]> Sat, 13 Oct 2012 07:49:02 -0700
| Newsgroups | gmane.comp.lang.e.general |
|---|---|
| Message-ID | <[email protected]> |
On Oct 12, 2012, at 2:16, Thomas Leonard wrote:
> It's generally useful to support backwards-compatible updates. e.g. a future version of the service might declare:
>
> struct User {
> name :String,
> email :Email,
> phone :nullOk[Phone] := null,
> }
>
> If a user registers with extra details that an old version doesn't need then it can just store them in the database anyway. No need to reject the message.
What comes to mind now is that there could be a pattern for extensible records: add a single field for extra data,
unknowns :Map[String, Data],
such that the User (version 1) guard coerces (using placeholder syntax!)
struct [
name = "Alice",
email = <mailto:[email protected]>,
phone = <tel:+5555555>,
]
into the typed struct
User [
name = "Alice",
email = <mailto:[email protected]>,
unknowns = ["phone" => <tel:+5555555>],
]
. That is, all unknown fields are stuffed into a plain Map (hm, or perhaps an untyped record). This keeps the record semantics simple for applications that don't want extensibility, and makes it easy to process extra fields if wanted. What do you think?
> (in OO terms, you might say e.g. "interface NewUser extends User", and
> services which need a User will also accept a NewUser)
That's a slightly different case -- then there exists a data type which knows the fields. In order to have this in my scheme, we'd have to essentially have a User guard which is "non-final" in the Java sense -- and then that raises the question of how much the behavior is allowed to vary.
--
Kevin Reid <http://switchb.org/kpreid/>