[e-lang] Bindings and guard-based auditing
Kevin Reid
kpreid at switchb.org
Tue May 25 21:39:08 PDT 2010
On May 25, 2010, at 14:42, Thomas Leonard wrote:
> On 25 May 2010 17:41, Kevin Reid <kpreid at switchb.org> wrote:
>> What do you mean by "binding types"?
>
> I'm assuming I can't do:
>
> def &&x := makeMyBinding(...)
Correct.
>> Note that 'CoercedSlot' does not mean 'a (container for a) slot which
>> has been coerced'; it means 'a slot whose value *has been* coerced';
>> it is basically GuardedSlot without the mutability.
>
> I'm still confused, then. How can the value have been coerced, unless
> it's a FinalSlot. Other slots change their value over time.
Statement #1, about the ELib component known as CoercedSlot:
A CoercedSlot is “final”. CoercedSlot is precisely to FinalSlot as
GuardedSlot is to VarSlot*: like FinalSlot, its value does not change,
and like GuardedSlot, it remembers a guard, and guarantees that its
value passed that guard.
Statement #2, about the use of such in guard-based auditing:
The binding for 'var x :int' is the object constructed by
makeCoercedSlot(GuardedSlot[int],
makeGuardedSlot(int, specimen, ejector),
ejector)
The binding-guard for this binding is GuardedSlot[int], which is
stored in the guard attribute of the binding object (which happens to
be a CoercedSlot object).
This is arguably a type pun; we are reusing the interfaces and naming
of slot objects because they happen to have the right properties (a
value and a guard) for binding objects. You could say 'a binding is a
meta-slot' in the same sense as 'metaclass'; a value is stored in a
slot (which is a Slot) which is stored in a binding (which is also a
Slot, and furthermore necessarily a CoercedSlot).
* See http://wiki.erights.org/wiki/Basic_slot_type_naming for issues
with the choice of names here.
> 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.)
(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.
(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 {} }
--
Kevin Reid <http://switchb.org/kpreid/>
More information about the e-lang
mailing list