home *** CD-ROM | disk | FTP | other *** search
-
- Franz lisp now has a form of closure called an fclosure. A fclosure is a
- compromise between a funarg and the type of functional object that we
- currently have in Franz. In this short note, I'll explain through examples
- what fclosures are and where you might use them, and finally describe the new
- functions. The fclosure system was designed to be compatible with the Lisp
- Machine closures, so you may want to look at a Lisp Machine manual for more
- information. fclosure are related to closures in this way:
- (fclosure '(a b) 'foo) <==> (let ((a a) (b b)) (closure '(a b) 'foo))
-
- A example of the use of fclosures:
-
- ->(setq counter 0)
- 0
- ->(setq x (fclosure '(counter) '(lambda (val) (setq counter (+ val counter)))))
- fclosure[1]
-
- The function 'fclosure' creates a new type of object called a fclosure.
- A fclosure object contains a functional object, and a set of symbols and
- values for the symbols. In the above example, the fclosure functional
- object is (lambda (val) (setq counter (+ val counter)))
- and the set of symbols and values just contains the symbol 'counter' and
- zero, the value of counter when the fclosure was created.
-
- When a fclosure is funcall'ed:
- 1) the lisp system lambda binds the symbols in the fclosure to their
- values in the fclosure.
- 2) it continues the funcall on the functional object of the fclosure
- 3) finally it un-lambda binds the symbols in the fclosure and at the
- same time stores the current values of the symbols in the fclosure.
-
- To see what that means, let us continue the example:
- -> (funcall x 32)
- 32
- -> (funcall x 21)
- 53
-
- Notice that the fclosure is saving the value of the symbol 'counter'.
- Each time a fclosure is created, new space is allocated for saving
- the values of the symbols.
- If we executed the same fclosure function:
- ->(setq y (fclosure '(counter) '(lambda (val) (setq counter (+ val counter)))))
- fclosure[1]
-
- We now have two independent counters:
- -> (funcall y 2)
- 2
- -> (funcall y 12)
- 14
- -> (funcall x 3)
- 56
-
- To summarize:
-
- (fclosure 'l_vars 'g_funcobj)
- l_vars is a list of symbols (not containing nil)
- g_funcobj is lambda expression or a symbol or another fclosure
-
- examples: (fclosure '(foo bar baz) 'plus)
- (fclosure '(a b) #'(lambda (x) (plus x a))) notice the #'
- which will make the compiler compile the
- lambda expression.
-
-
- There are time when you want to share variables between fclosures.
- This can be done if the fclosures are created at the time times using
- fclosure-list:
-
- (fclosure-list 'l_vars1 'g_funcobj1 ['l_vars2 'g_funcobj2 ... ...])
- This creates a list of closures such that if a symbol appears in
- l_varsN and l_varsM then its value will be shared between the
- closures associated with g_funcobjN and g_funcobjM.
-
- example: -> (setq x (fclosure-list '(a) '(lambda (y) (setq a y))
- '(c a) '(lambda () (setq c a))))
- (fclosure[4] fclosure[7])
- -> (funcall (car x) 123) ; set the value of a in the 1st fclosure
- 123
- -> (funcall (cadr x)) ; read the same value in the 2nd fclosure
- 123
-
-
- Other fclosure functions:
-
- (fclosure-alist 'c_fclosure)
- returns an assoc list giving the symbols and values in the fclosure
-
- (fclosurep 'g_obj)
- returns t iff g_obj is a fclosure
-
- (fclosure-function 'c_fclosure)
- returns the functional object of the fclosure
-
-
-
- Note: If a throw (or error) occurs during the evaluation of a fclosure,
- which passes control out of the fclosure, then current values of the
- symbols will not be stored. This may be a bug. We could set up
- an unwind-protect, but it would then take longer to funcall
- a fclosure. If you think an unwind protect is important, let me know.
-
- Note 2: you can also 'apply' a fclosure.
-
-
-
-
-
-
-