Path: utzoo!attcan!uunet!seismo!esosun!jackson From: jackson@esosun.UUCP (Jerry Jackson) Newsgroups: comp.lang.scheme Subject: binding and assignment Message-ID: <238@esosun.UUCP> Date: 26 Jul 88 13:53:26 GMT Organization: SAIC, San Diego Lines: 93 It occurred to me that there is an inconsistency in the scheme/lisp treatment of assignment when it comes to symbols -- in all other cases assignment means changing the contents of a cell of some kind, while assignment to a symbol is treated as a renaming operation. I figured this had resulted from the functional programming perspective -- a binding is simply the name for a value in a particular context... It seems non-intuitive that assigning to "a" is actually removing the name "a" from some value and naming a different value "a". I thought that a slightly different model might be useful -- Let binding be an irrevocable operation. Create a new data type called a "variable" that has the following property -- When a variable is returned from eval, it is dereferenced so that its contents are returned, except when it is the first argument to a set! special form or the result of a 'var' special form. My intent is that 'variable' is the only mutable data type -- I'll give a few examples before explaining the benefits of this model: (define fact (lambda (n) (if (< n 2) 1 (* n (fact (1- n)))))) defines fact as you would imagine and works the same way you would think -- however, following this with: (set! fact 5) would return an error -- fact is not bound to a variable After evaluating: (define fact2 (var (lambda (n) (if (< n 2) 1 (* n (fact2 (1- n))))))) (fact2 x) would give the same result as (fact x), but (set! fact2 5) would succeed. Note: typing "fact2" at this point would return 5, but the expression: (var? fact2) -> t while (var? fact) -> nil This produces several benefits: 1) the 'setf' form of CL is obtained for free in a much less kludgey way -- e.g. after: (define w (list (var 3) (var 4))) => w = (3 4) evaluating: (set! (cadr w) 5) would cause w to appear as: (3 5) 2) built-in functions can be defined at the top level without using the 'var' form so that they cannot be redefined... 3) the need for things like "named-lambda" is lessened -- If a recursive function is defined without using 'var', the value will never change and you get the effect of a named-lambda for free 4) assignment becomes completely consistent and only one assignment special form is needed instead of one for each type of mutable data -- It is no longer necessary to have vector-set!, set-car!,... 5) quoted constants are now actually guaranteed to be constant -- no more accidental program modification 6) inlining (or direct linking -- not through a symbol) of built-ins is now allowable without constraints Any comments? +-----------------------------------------------------------------------------+ | Jerry Jackson UUCP: seismo!esosun!jackson | | Geophysics Division, MS/22 ARPA: esosun!jackson@seismo.css.gov | | SAIC SOUND: (619)458-4924 | | 10210 Campus Point Drive | | San Diego, CA 92121 | +-----------------------------------------------------------------------------+