Annotation of researchv10no/cmd/sml/doc/callcc, revision 1.1

1.1     ! root        1: A set of new primitives has been added to ML to give access to continuations:
        !             2: 
        !             3: type 'a cont
        !             4: val callcc : ('a cont -> 'a) -> 'a
        !             5: val throw : 'a cont -> 'a -> 'b
        !             6: 
        !             7: The continuation of an expression is an abstraction of what the system
        !             8: will do with the value of the expression. For example in the
        !             9: expression:
        !            10: 
        !            11:                 if a orelse b then foo() else goo()
        !            12: 
        !            13: the continuation of the expression "a orelse b" can be described in
        !            14: words as "if the value is true then compute foo() otherwise compute
        !            15: goo()" and then continue in the context of the if-expression. Usually
        !            16: the continuation of an expression is implicit, however, the primitive
        !            17: callcc allows the programmer to capture and use these continuations.
        !            18: 
        !            19: The primitive callcc takes a function as an argument and applies it to
        !            20: the current continuation.  The continuation of an expression of type 'a
        !            21: has type 'a cont and is a first-class object. To capture the
        !            22: continuation described above one would write:
        !            23: 
        !            24:    if callcc(fn k => a orelse b) then foo() else goo
        !            25: 
        !            26: Here the continuation of the callcc-application is captured by being
        !            27: bound to k, but it is not used. Because the continuation is not used
        !            28: the result is simply the result of the expression "a orelse b".  To
        !            29: use the continuation a value must be supplied, and the computation
        !            30: continues as if that value where the result of the callcc-application.
        !            31: This is called throwing the continuation a value; it is performed by
        !            32: applying "throw" to the continuation and the value.
        !            33: 
        !            34:  if callcc(fn k => (throw k false) orelse b) then foo() else goo()
        !            35: 
        !            36: Here, when the continuation k is thrown the value false, "orelse b" is simply
        !            37: ignored, the callcc-application returns false, and goo() is then evaluated.
        !            38: 
        !            39: The type returned by a throw-expression is unconstrained like that of
        !            40: a raise-expression and for the same reason:  neither of these
        !            41: expressions ever return.
        !            42: 
        !            43: One of the less interesting uses of callcc is as an alternative to
        !            44: exception handlers. For example:
        !            45: 
        !            46:     exception Prod
        !            47: 
        !            48:     fun prod l = let fun loop [] = 1
        !            49:                       | loop(0::r) = raise Prod
        !            50:                       | loop(a::r) = a * loop r
        !            51:                 in loop l handle Prod => 0
        !            52:                 end
        !            53: 
        !            54: can be written with callcc as follows:
        !            55: 
        !            56:     fun prod l = callcc(fn exit => 
        !            57:                           let fun loop [] = 1
        !            58:                                 | loop(0::r) = throw exit 0
        !            59:                                 | loop(a::r) = a * loop r
        !            60:                           in loop l
        !            61:                           end)
        !            62: 
        !            63: But continuations are more general than exception handlers and can be
        !            64: used to implement sophisticated control structures. These more complex
        !            65: uses often involve subtle interactions with the type system.  For just
        !            66: a taste of the techniques involved consider the following example
        !            67: implementing an infinite loop.
        !            68: 
        !            69:     datatype State = S of State cont 
        !            70:     fun state_throw (S k) = throw k
        !            71: 
        !            72:     let val s = callcc S
        !            73:     in state_throw s s
        !            74:     end
        !            75: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.