Re: Interfaces / data types in E
Thomas Leonard <tal-v5nx5w6akNyLE8xUarVfuPLx9OUvmyODWmv/[email protected]> Thu, 06 Oct 2011 16:27:11 +0100
| Newsgroups | gmane.comp.lang.e.general |
|---|---|
| Message-ID | <[email protected]> |
On 2011-10-06 11:50, Kevin Reid wrote:
> On Oct 6, 2011, at 6:35, Thomas Leonard wrote:
>
>> We've got quite a few methods that take or return maps. e.g.
>>
>> to purchase(customerDetails :Map[String,any]) { ...
>> customerDetails["name"] ... ... if (problem) {
>> notify(customerDetails["email"]) } ... }
>
> When you say "We" do you mean the E project or one of yours?
One of mine.
>> The problem is that it's not obvious from the method signature what
>> keys need to be present. Often someone fails to include a mapping,
>> and the system only fails later in some case where it needed that
>> value.
>>
>> What I think I'd like to do is something like:
>>
>> def CustomerDetails := makeNamedTuple([ "name" => String, "email"
>> => String, ])
>>
>> ...
>>
>> to purchase(customerDetails :CustomerDetails]) { ...
>> customerDetails["name"] ... }
>
> I think this is a fine guard to have. For consistency with other
> parameterized guards, it should be written NamedTuple[[...]].
Good idea.
> Also, I think a better name would be "Record", with one caveat: we
> may wish to introduce record objects at a later time which have
> explicitly defined type objects and non-dynamic fields. Thus perhaps
> "MapRecord" instead...?
>
>> So that:
>>
>> - if the caller fails to provide "name" and "email" then it fails
>> the guard - if I try to access a field I didn't define (e.g. "fax")
>> then I get an error, whether or not the client provided it, so I'm
>> forced to keep the interface up-to-date
>
> The latter requires that the guard wrap its parameter. That is a
> perfectly fine thing to do, but it shouldn't be "normal behavior" and
> so should be clearly indicated in a noun or verb.
Yes, I'm not very happy about the wrapping (especially if you then try
to send the wrapped object over the network). Thinking further, I guess
what I really want is a compile-time check (if something has a
:CustomerDetails guard then it's a compile-time error to use a field not
defined by that type). E doesn't make it easy to add these kinds of
checks at the moment.
>> Any ideas on the best way to do this? Maps? TermTrees?
>
> Term-trees are not suitable for general purposes because they cannot
> contain arbitrary objects (not even arbitrary Data objects).
Good point. We often send SturdyRefs around in these structures.
>> Some of the other systems using this are written in Java, so
>> ideally it should be easy to use from there too.
>
> Since Java idiom would be to define a class to hold the record
> contents, this suggests that the record objects I mention above would
> be a better E idiom than using Maps, if you want interoperation.
How do they work?
--
Dr Thomas Leonard
IT Innovation Centre
Gamma House, Enterprise Road,
Southampton SO16 7NS, UK
tel: +44 23 8059 8866
mailto:tal-v5nx5w6akNyLE8xUarVfuPLx9OUvmyODWmv/[email protected]
http://www.it-innovation.soton.ac.uk/