(ref.doc)pd130395

Next pd111095 Prev: pd060395 Up: pat

Date: Mon, 13 Mar 1995 10:38:08 -0600
Originator: [email protected]
From: Thomas Kuehne <[email protected]>
Subject: Pattern: Function Closure

I hope this is the correct list for presenting patterns.
I am not sure whether [email protected] still lives so I am repeating
the mail here.

The main reason why I wrote this is that there was no connection between
Iterator and Command in the GOF book.
IMO, there clearly is one and so I take the effort and present a pattern
which is similar to Command but extends it. One might argue it is 
a combination of two Patterns: Command (with result) and 
Partial Parameterization (not at structural but rather a technique pattern).
In order to make it a good pattern description I should invest more work,
but I want to test the acceptance for a 'variation on Command' first.


Name:   Function Closure


Intent: Encapsulate a function as an object, thereby letting you benefit
        from many attractive features from functional programming, such
        as: Higher order functionality, Currying, lazy evaluation,
        infinite data structures.

        Note, that Function Closure without partial parameterization
        (Currying) and with a function that produces side-effects only,
        boils down to the Command pattern.

        Reversely Function Closure may also be used where Command is used,
        e.g. separate callers and servers and undoing.


Also Known As:
        *Agent-Object*, which has been indepently used by me [SIG94] and
        Andrew Koenig (for the Booch Components).
        In order to avoid confusion with intelligent- or distributed-
        Agents I called it *Function Object* [TOOLS94].
        In a pattern context the term 'Object' is not necessary and
        'Closure' nicely serves to demonstrate the difference to Command.


Motivation:
        Choosing an OO-language should not mean that one is deprived of
        all goodies of a functional language.
        Whereas Smalltalk programmers frequently use blocks for higher
        order functionality,  C++, Eiffel, etc. programmers are normally forced
        to use function pointers or inheritance as substitutes.
        Function Closure truncates an object to a single method with
        an attribute environment. Thus it can be used just like a
        function in a functional language:

        o It can be passed to other objects (e.g. pass a compare
          predicate to a sorter).

	o It can be partially parameterized (e.g. pass "H.G. Wells"
          to a predicate you used for sorting books according to titles and
          use it to find a book in a binary search tree).

	o It can produce other function closures (which is one way
          to implement currying).

        o It can accept other function closures (e.g. a function 
          performing actions on books might take a test function closures
          that it asks whether to perform the action or not).

        o It can be composed of other functions (similar to MacroCommands).

	o It can be used to postpone an evaluation until it is needed.

        o Data structures may use function closures to defer their
          contents to calculation, enabling infinite data structures.

        o It can be used where ever Smalltalk blocks are used.
          Whereas Smalltalk blocks bind the environment to
          free variables implicitely, this has to be done explicitely.

        o As it subsumes Command it can be used where ever Command is used
	  (e.g. Callback function for Window-Interface).

          Note, that partial parameterization is handy here as well.
          Imagine the interface has changed, that is, more parameters
          are needed to control appearance (e.g. consider the change
          from textual output to a graphical alert).
          The client that calls the Function Closure does not need to
          provide the additional parameters and thus needs not to be
          changed, since we can pass the additional parameters to
          the Function Closure previous to passing it to the client.


Implementation

	This is similar to Command but there are options how to
        realize partial parameterization.
        Either currying is implemented by producing a new Function Closure
        as a result of supplying an argument to a Function Closure or
        by internally counting the received arguments, dispatching them
        to appropiate attributes.
        Providing full parameterization (that is any order of supplying
        arguments is allowed) widens the interface of Function Closures.
        With the reasonable restriction of partial parameterization to
        currying Function Closures uniformly support
        
	o 'supply(...)', which takes an argument
        o 'evaluate', which produces the function result.


Related Patterns:

	The most frequent collaboration will be with Iterator.
        Function Closures enable C++, Eiffel, etc. programmers
        to benefit from internal iterators as Smalltalk programmers
        natively can. Iterator is passed a Function Closure and 
        passes each of it's elements to the Function Closure subsequently.
	Typically the result of each call will be assigned back to the
        element, but it is also possible to use side effects on elements.


If there is interest I want to add a short discussion on internal/external
iterations and why I think that Eiffel and Smalltalk should exchange their
philosophies on implementing iteration  a) in data structures or  b) extra
iteration classes. I'd like to do it now but our sysop shuts down
the system for a while :(


References:

[SIG94] Thomas K�hne "Higher Order Objects in pure Object-Oriented Languages"
        ACM SIGPLAN NOTICES Volume 29, Number 7, 1994

[TOOLS94] Thomas K�hne "Inheritance versus Parameterization"
          Proceedings of the 15.th conference of Object-Oriented Languages
          and Systems: TOOLS Pacific 1994, pages 235-245,
          Prentice Hall
          "Proceedings contain premature layout version:
           For correct versions please address the author"

automatically generated by info2www version 1.2.2.8