Path: utzoo!attcan!uunet!tut.cis.ohio-state.edu!husc6!purdue!iuvax!copper!raja From: raja@copper.ucs.indiana.edu (Raja Sooriamurthi) Newsgroups: comp.lang.lisp Subject: Re: Lisp 1.5 functional values as objects Message-ID: Date: 10 Oct 90 14:39:10 GMT References: <1950001@hpgnd.HP.COM> Sender: news@iuvax.cs.indiana.edu Lines: 91 dave@hpgnd.HP.COM (Dave PENKLER) writes: >A recent discussion on whether CL functions are first class objects brought up >a point on the run time creation of functions. This is somthing I missed in CL >and have consequently remained stranded in the ancient world of Ye Old Lisp. >Ye old lisp's abilty to handle functional values can be interpreted as a sort >of support for object oriented development. The beauty of it is its extreme >simplicity in the prinicple of operation permitting at the same time >arbitrarily complex hierachies and collections of objects. For free you have >the ability to modify methods in a given instance, all instances of a class >or future instances. This is great for modelling and simulations where >you may need to tweak individual instances during the run to see what the >effects on the system might be. Dynamic scoping gives you what I call dynamic >inheritance where free variables/methods in the closure are resolved in the >invoking environment and captured in the instance. >Here is an ultra simple example to give the basic idea of functional values >as objects: >To create a class you simply define a function that returns itself in a funarg - > (defun SIMP (X Y) ; inittable instance vars X and Y > (prog (Z SHOW) ; instance var Z and a method SHOW > (setq Z 'some-default) ; initial value of Z > (defun SHOW () (print (list X Y Z))) ; method to print instance vars > (fun SIMP))) ; return self in funarg >To create an instance - >(setq INST1 (SIMP 'fred 'joe)) >To apply the method SHOW to our instance - > (send '(SHOW) INST1) ; show its guts >(fred joe some-default) >The real work here is done by "send" >(defun send (EXP OBJ) (apply (list 'close (car EXP) (caddr OBJ)) (cdr EXP))) >Is there any way to do this sort of thing in newer dialects of lisp ? ^^^^^^^^^^^^^^^^^^^^^^ This might be out of place in this news-group, but Scheme can handle these sort of objects very elegantly. For instance a stack could be defined as: (define make-stack (lambda () ; if desired initial values could be passed here (let ([stack 'any-initial-value]) (lambda msg ; the function (object) that is returned (case (car msg) [push (set! stack (cons (cadr msg) stack))] [pop (set! stack (cdr stack))] [top (car stack)] [show stack] [flush (set! stack 'any-initial-value)] [else (error 'stack "unknown method name")]))))) (define send (lambda args (apply (car args) (cdr args)))) You would create stacks as: (define s1 (make-stack)) and manipulate it as: (send s1 'push 'apple) (send s1 'push 'orange) (send s1 'show) ... In this style of creating objects, values can be shared between different classes by means of delegation. Springer and Friedman devote an entire chapter to this mechanism of creating objects in their book _Scheme and the art of Programming_ (MIT press and McGraw Hill, 1989) - Raja --------------------------------------------------------------------------- Raja Sooriamurthi Computer Science Department raja@copper.ucs.indiana.edu Indiana University ---------------------------------------------------------------------------