Path: utzoo!utgpu!water!watmath!clyde!att!rutgers!ucsd!ucbvax!decwrl!sun!pitstop!sundc!seismo!uunet!mcvax!ukc!warwick!cvaxa!aarons From: aarons@cvaxa.sussex.ac.uk (Aaron Sloman) Newsgroups: comp.lang.lisp Subject: Re: What's the value of lexical scoping? Keywords: Scope, Binding, Locals, Future of LISP, POP-11 Message-ID: <486@cvaxa.sussex.ac.uk> Date: 24 Jun 88 07:03:22 GMT Organization: School of Cognitive Sciences, Univ of Sussex, Brighton, UK Lines: 127 From: simon@comp.lancs.ac.uk (Simon Brooke) >Part of the power and expressiveness of LISP is that we can, >when we want to, and when we know what we're doing, write functions which >are sensitive to changes in their environment. If you don't like this, you >will find that there are plenty of other *very good* languages (Pascal, >Modula, Ada - even Scheme) which cater for your needs. Don't come and mess >up the one language which has the expressiveness to do this. The "one" language? No. Pop-11 is another language that allows dynamic scoping. (For those who don't know it, there's an enthusiastic review of Alphapop, a subset of Pop-11 for the Mac, in Byte May 1988). The full version of Pop-11, currently available only in the Poplog system, allows both lexical and dynamic scoping. For historical reasons dynamic scoping is the default (ie input and output local parameters default to being dynamically scoped if not explicitly declared lexical (using "lvars", "lconstant" or "dlvars"). Pop-11 is a sort of mixture of Lisp (dynamic scoping is available, along with macros, lists garbage collection, etc), Scheme (functions are ordinary values of variables, and in all respects first class objects, and lexical scoping is available), Pascal (rich, readable syntax, records, arrays), Forth (use of explicit stack for passing arguments and results). It also includes partial application, a pattern matcher, a lightweight process mechanism and tools for creating new incremental compilers, which is how the Poplog system can include compilers for a variety of languages (Pop-11, Prolog, Common Lisp, ML, and other user-implemented languages). Pop-11 is a much expanded derivative of Pop-2 the language that was used for many years in the Edinburgh Universith AI department. One interesting fact about Pop-11 is that when lexical scoping became available (version 10.2 1985) many users (including the Poplog system developers) found themselves switching from dynamic scoping as their default to lexical, (a) because they produced were fewer bugs due to unintended interactions between procedures taking procedures as arguments, (b) because it improved efficiency. Moreover, they also became aware of additional expressive power available. E.g. here's a procedure that takes two procedures and returns a third procedure which is their functional composition: define compose(f1, f2); lvars procedure (f1, f2); define lvars f3(x); f2(f1(x)) enddefine; return(f3) enddefine; So, using it: vars root4; compose(sqrt,sqrt) -> root4; root4(16) => ** 2.0 A procedure that takes a start number and an increment number and returns two procedures, a number generator and a "reset" procedure: define make_generator(start, incr) -> generator -> reset; lvars start, incr, generator, reset, count=start; ;;; create the number generator procedure procedure(); count; ;;; result left on stack count + incr -> count; ;;; increment for next time endprocedure -> generator; ;;; procedure assigned to generator procedure(); start -> count; endprocedure -> reset; ;;; procedure assigned to reset enddefine; vars gen1, reset1, gen2, reset2; ;;; declare some global variables ;;; Create two generators and their "reset" procedures, one to ;;; generate multiples of 3, the second multiples of 5. make_generator(3,3) -> gen1 -> reset1; make_generator(5,5) -> gen2 -> reset2; gen1() => ;;; run gen1 and print out its result ** 3 gen1() => ** 6 gen2() => ** 5 gen2() => ** 10 ;;; reset the first sequence reset1(); gen1() => ** 3 gen2() => ** 15 So, using lexical scoping it is very easy to define a procedure that (each time it is invoked) creates a family of procedures that share a private environment. (For some of the simpler cases you can also do this using partial application, which is a bit more efficient, though less elegant). I suspect Lisp (and therefore perhaps AI) would have a much healthier future as a general purpose language if it used the richer, more readable (for ordinary mortals), syntax of Pop. Cheers Aaron Sloman, School of Cognitive Sciences, Univ of Sussex, Brighton, BN1 9QN, England ARPANET : aarons%uk.ac.sussex.cvaxa@nss.cs.ucl.ac.uk aarons%uk.ac.sussex.cvaxa%nss.cs.ucl.ac.uk@relay.cs.net JANET aarons@cvaxa.sussex.ac.uk BITNET: aarons%uk.ac.sussex.cvaxa@uk.ac or aarons%uk.ac.sussex.cvaxa%ukacrl.bitnet@cunyvm.cuny.edu As a last resort (it costs us more...) UUCP: ...mcvax!ukc!cvaxa!aarons or aarons@cvaxa.uucp