[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

*To*: scheme@mc.lcs.mit.edu*Subject*: Re: Update functions in Scheme.*From*: Barak.Pearlmutter@F.GP.CS.CMU.EDU*Date*: Tue ,10 May 88 18:55:00 EDT*Cc*: bap@f

Interestingly, in Oaklisp the interaction between COMPOSE and SETTER that Bard Bloom desires is easy to obtain in a modular way, due to the way that settable operations are plugged into the type system: (define compose (make operation)) (add-method (compose (operation) f g) (lambda (z) (f (g z)))) (add-method (compose (settable-operation) f g) (let ((fg (make settable-operation))) (add-method (fg (object) z) (f (g z))) (add-method ((setter fg) (object) z x) (set! (f (g z)) x)) fg)) [ Lets exhibit modularity by making this work for locatable operation too: (add-method (compose (locatable-operation) f g) (let ((fg (make locatable-operation))) (add-method ((locater fg) (object) z) (make-locative (f (g z)))) fg)) ] ================== Of course, the problem of getting (DEFINE (FOO X) (BAR X)) to make FOO just as settable as BAR is not so easily addressed. The difficulty here is local variables, so one approach is to get rid of all the variable by translating everything down to a set of combinators. For instance, (define (foo a b) (if a (car b) (car (cdr b)))) would first get curried to (define foo (lambda (a) (lambda (b) (if a (car b) (car (cdr b)))))), while we note that (SET! (FOO X Y) Z) gets curried to (SET! ((FOO X) Y) Z). Some nesting gets removed (define foo (lambda (a) (lambda (b) (if a (car b) (((compose car) cdr) b))))), we get rid of B (define foo (lambda (a) (if a car ((compose car) cdr)))), and use the combinator which could be defined as follows: (define %if (lambda (f) (lambda (g) (lambda (test) (if test f g))))) to rewrite FOO to (define foo (%if car ((compose car) cdr))). Now, assuming that %IF carries through settableness (which it should do automatically the way Oaklisp COMPOSE did above), i.e. (setter ((%if f) g)) <=> ((%if (setter f)) (setter g)), our side effect attempt (set! ((foo x) y) z) gets macroexpanded to (((setter (foo x)) y) z) which works. In order to demonstrate that it works, we can work things through. Substituting in foo's definition, we have (((setter ((%if car) ((compose car) cdr))) y) z) which is the same as ((((%if (setter car)) (setter ((compose car) cdr))) y) z) which is the same as ((((%if (setter car)) ((compose (setter car)) cdr)) y) z) which, decurrying and reintroducing some variables, is the same as ((%if (lambda (b) ((setter car) b z)) (lambda (b) ((setter car) (cdr b) z)) x) y z) which is the same as (if x (set! (car y) z) (set! (car (cdr y)) z)). I find it more than a little perverse to use combinators in an effort to make side effects more convenient. --Barak. Acknowledgments: I would like to thank Peter Lee for his moral support.

- Prev by Date:
**Re: ``Update functions'' in Scheme.** - Next by Date:
**``Update functions'' in Scheme.** - Previous by thread:
**Please remove me.** - Next by thread:
**[no subject]** - Index(es):