Re: Idle musings on doing E over again

Kevin Reid <kpreid-M/[email protected]> Sun, 7 Oct 2012 08:43:20 -0700
Newsgroups gmane.comp.lang.e.general
Message-ID <[email protected]>
On Oct 2, 2012, at 4:24, Thomas Leonard wrote:

> On 1 October 2012 16:44, Kevin Reid <kpreid-M/[email protected]> wrote:
> In E, I could provide a single server object and do the database
> access myself (or using one of the Java libraries), but then I lose
> the security benefits of e.g. passing users SturdyRefs.

If I recall correctly, the identityMgr has a 'fault handler' which lets you handle swissnum lookups. That seems like it would be sufficient to allow use of SturdyRefs with lazy-loaded objects. If not, please explain how.

> I made a custom system which revives E objects lazily from a database,
> but there should be something provided by the standard library (my
> system doesn't evict objects from memory either, so it only helps
> start-up time; it doesn't stop the server running out of memory).
> Probably not a language issue, except that E provides timeMachine in
> privilegedScope.

Well, it is somewhat of a 'language issue' that there exist a standard serialization tool which reflects the whole-vat scope of synchronicity and failure, but there's no particular reason it has to be the only one (hence the whole tearOffRoots protocol).

> E's problem here is that it defines many things as runtime errors,
> rather than compile-time. Warnings are good, but errors are better, if
> possible. Also, there's a difference between:
> 
> - "This will certainly fail", and
> - "This could fail in some situations"
> 
> e.g.
> 
> def foo(a, b) { return a + b }
> 
> is OK for E, but a staticly checked language would require you to
> prove that "a" would have an "add" method which could accept "b" in
> all cases. Of course, these compile-time errors can also become
> run-time when running over a network against untrusted remote code (or
> link-time, with out-of-date compiled code).

Uncautiously declaring "This is an error, but only if we can prove it so" is a bad idea, because it means that whether your code is runnable depends on the cleverness of the implementation. I agree that early indications of failure are good to have; we'll see how strict they can be made.

>> What type of static type system do you have in mind?
> 
> No idea. Haskell is nice. ATS is a bit over-the-top ;-) Java would be
> OK if it handled nulls and generics better.

Haskell's variety of type system has a number of disadvantages; one is (I understand) that it cannot handle OO-style subtyping; a particular value must belong to exactly one concrete type. (I'm not sure exactly how type classes fit in to this.)

> So I can say e.g.:
> 
> struct User {
>  name :String,
>  email :Email
> }
> 
> def register(u :User) { ... }
> 
> If "u" is received over the network then the system should verify its
> structure and reject it if it's wrong. But when passing between
> functions within a vat, it shouldn't keep rechecking it.

Yes, this is what I have in mind. In particular, what I am currently thinking is: records have an optional "type" reference. When the User guard gets an untyped (or wrong-typed?) record, it checks the record against the declared structure and produces a new record with the matching type. Thus, if the type already matches we have an O(1) check after the conversion.

Thus we can have records with just as much type information as real objects, but not require the creator of a record to have a reference to the type object (or, for network cases, to have a reference to the *same* type object). This is particularly relevant because (given sufficiently nice syntax) I want to use records as the standard solution to keyword arguments.

On the grounds of keeping the language small, what do you think of a quasi, i.e.
  def makeUser := struct`
    name :$String
    email :$Email
  `
?


On the other hand, another potentially valuable facility would be some way to avoid rerunning guards on an object even if they are purely structural guards. I've thought about providing a generalized cache for this purpose; I don't know whether doing so will turn out to be feasible (i.e. provide more performance benefit than cost).

-- 
Kevin Reid                                  <http://switchb.org/kpreid/>