[e-lang] Thought: DeepFrozen too restrictive for guards?

Mark S. Miller markm at cs.jhu.edu
Thu Apr 27 13:32:39 EDT 2006

Kevin Reid wrote:
> The plan has been to require that all objects in guard positions are  
> DeepFrozen. [...] For example:
>    def Deopt { 
 >        to get(default) {
 >            def guard {
 >                to coerce(specimen, _) {
>                    return if (specimen == null) {specimen} else {default} 
 >                }
 >            }
 >            return guard
 >        }
 >    }
>    def ...(..., log :Deopt[stdout]) {
>    }
> would be rejected since stdout isn't DeepFrozen.

[Example code above re-indented, 'deopt' renamed 'Deopt', and missing
  'return guard' inserted.]

Kevin, Dean, and I had a long conversation last night examining Kevin's
option #3:

> 3a. Introduce the guard-but-not-DeepFrozen operator (which I've  
> mentioned before, though possibly not on e-lang).
>      It would be identical to the : pattern but with a different  
> symbol, and possibly using 'run' or 'match' instead of  
> 'coerce' (since these Are Not Guards Since They Aren't DeepFrozen).
>      Problems: Hard to find a good syntax for it.

The syntax we found attractive is one that Kevin had previously proposed in a 
different context: The 'via' keyword used in place of a colon between a 
pattern and an expression. The expression's value will be invoked as a 
function, i.e., via will use 'run' instead of 'coerce' as Kevin suggests above.

Kevin's above example, written using 'via', looks like

    def deopt(default) {
        def deopter(specimen, _) {
            return if (specimen == null) {specimen} else {default}
        return deopter

    def ...(..., log via (deopt(stdout))) {

Although ':' and 'via' patterns will both be in Kernel-E, we can still explain 
the semantics of ':' in terms of 'via':

    def i :int := j

would be equivalent[*] to

    def i via (makeViaAdaptor(int)) := j

given a makeViaAdaptor defined as

    def makeViaAdaptor(guard :DeepFrozen) {
        def viaAdaptor(specimen, optEjector) {
            return guard.coerce(specimen, optEjector)
        return viaAdaptor

[*] This isn't actually equivalent in three ways:

1) I don't propose to provide a makeViaAdaptor in the safe scope, and perhaps
    not at all.
2) Any reflective primitive, such as auditing, that makes available the
    Kernel-E AST would reveal the difference between two expressions that are
    otherwise equivalent. All statements of the form that "expressions x and y
    are semantically equivalent" must be understood as qualified by this issue.
3) Kevin, Dean, and I discussed Zooko's recent proposal for a change to the
    auditing protocol, which I will explain in a later email message. Zooko's
    proposal has the auditing framework treat as special the guard on a
    variable definition. The above rewrite would hide the guard from the
    auditing framework, changing the meaning of the program. More on this soon.

Text by me above is hereby placed in the public domain


More information about the e-lang mailing list