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