Re: Bindings and guard-based auditing

Thomas Leonard <[email protected]>
Newsgroups gmane.comp.lang.e.general
Message-ID <[email protected]>
OK, so a summary of the problems with getting DeepFrozen working (with
the goal of letting ImportLoader cache things):

- Verbose syntax for defining objects ("implements DeepFrozen" everywhere)

- No syntax for writing DeepFrozen functions (the most common thing we
need to audit!)

- Unguarded values can't be audited:

  def x := 3
  def myObject implements DeepFrozen { to getX() { return x } }

  (audit fails because 'x' has no guard)

- Auditing everything is hugely slow anyway because the auditing
mechanism uses Java exceptions. Just calling
DeepFrozenAuditor.THE_ONE.audit on each object increases E's startup
time from 6s to 22s, even when all it does is just throw an exception.

- Not clear how to audit objects that refer to themselves.

- Many Java objects will need to be tagged as DeepFrozen, which is
likely to be error-prone and tricky. Is a broken reference DeepFrozen,
for example? It contains an arbitrary Throwable...

- DeepFrozenAuditor is in elib, so it can't access the types it needs
(ObjectExpr, etc), as they're in elang.

- Much of safeScope is populated with lazy-slots to objects with
recursive definitions (e.g. "int"). Unless the auditor can handle
these complex cases, almost nothing will pass.

Suggestions?


On 26 May 2010 15:53, Thomas Leonard <[email protected]> wrote:
> On Wed, 2010-05-26 at 00:39 -0400, Kevin Reid wrote:
>> On May 25, 2010, at 14:42, Thomas Leonard wrote:
> [...]
>> > By the way, I'm assuming we'll just audit everything for DeepFrozen
>> > automatically whenever possible, or my fingers will get very tired
>> > from typing "implements DeepFrozen" everywhere.
>>
>> No. This would form an unavoidable one-bit implementation information
>> leak. Feel free to suggest syntax and naming changes to reduce the
>> verbosity. (You can always 'def &&DF := &&DeepFrozen', of course.)
>
> How can I write a function then?
>
> def add(x, y) { return x + y }
>
> becomes
>
> def add as DeepFrozen {
>        to run(x, y) { return x + y }
> }
>
> Why would leaking that something isn't DeepFrozen be a problem?
>
>> (Random thought: This would all be much simpler if E did not have non-
>> final-slots and all mutation or otherwise special slots were handled
>> by user code working with explicit slot objects...)
>>
>> > Well, let's add the auditor first, instead of ...:
>> >
>> > interface FooGuard guards FooAuditor {}
>> > def foo implements FooAuditor {}
>> > def bar implements Nonsklarkish { ... foo ... }
>> >
>> > In both proposals, the Nonsklarkish can't see anything about foo in
>> > this case, I think.
>> >
>> > To make it available, I'd assume this:
>> >
>> >  def foo :FooGuard implements FooAuditor {}
>> >
>> > Then Nonsklarkish knows that foo was coerced by FooGuard, because "def
>> > var :guard" exposes "guard" to auditors automatically.
>>
>> This notion causes a circularity problem with the object's self-
>> reference. (It also makes another lookahead mess in the parser, but
>> we've got lots of those already in object/def expression heads.)
>>
>> def a {
>>    to coerce(sp, ej) {
>>      return sp.this()
>>    }
>> }
>>
>> def b :a {
>>    to this() {
>>      return b
>>    }
>> }
>>
>> The value of b is not determined until the guard a returns, but a
>> invokes b. Therefore the naming pattern of an object expression must
>> not have a guard.
>
> That is annoying, but it's a problem E already has in other places (e.g.
> "def foo extends makeBar(foo)"). For the cases supported by the "as"
> syntax, there's no reason why the guard would call the object anyway.
>
> I find it odd that we're being so careful to restrict what auditors can
> see and do, yet guards are so powerful:
>
> def obj as Auditor { ... }
>
> def process(x :Guard) { ... }
> process(obj)
>
> The guard is free to substitute a replacement for obj, changing its
> behaviour completely or getting access to every value passed to it.
>
>> (Making b-inside-of-b be a promise until the guard returns makes a
>> messy edge case for auditors, but might be workable...)
>
>> > Presumably for bindings the syntax would be:
>> >
>> >  def foo as FooAuditor {}
>> >
>> > But that gives Nonsklarkish the powerful FooAuditor, which seems
>> > wrong, so I don't think I've understood this syntax.
>>
>> It is inappropriate to use the 'as' syntax for rubber-stamps, yes. You
>> should really call it 'FooStamp' to indicate that it is a stamp.
>> Rubber-stamps are a degenerate, but supported, case of auditors.
>>
>> Instead of using the 'as' syntax, you'll have to use the separate
>> guarding syntax.
>>
>> def foo :Foo := { def foo implements FooStamp {} }


-- 
Dr Thomas Leonard        ROX desktop / Zero Install
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA

_______________________________________________
e-lang mailing list
[email protected]
http://www.eros-os.org/mailman/listinfo/e-lang
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.